1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

Pipemode now works for detached binary signatures.

This commit is contained in:
Werner Koch 2000-12-11 19:54:59 +00:00
parent 070c07c10f
commit 335dcec55b
7 changed files with 167 additions and 21 deletions

View file

@ -1,3 +1,11 @@
2000-12-08 Werner Koch <wk@gnupg.org>
* pipemode.c: Made the command work. Currently only for
non-armored detached signatures.
* mainproc.c (release_list): Reset the new pipemode vars.
(add_gpg_control): Handle the control packets for pipemode
* status.c, status.h: New stati {BEGIN,END}_STREAM.
2000-12-07 Werner Koch <wk@gnupg.org>
* g10.c: New option --allow-secret-key-import.

View file

@ -72,6 +72,10 @@ struct mainproc_context {
ulong local_id; /* ditto */
struct kidlist_item *failed_pkenc; /* list of packets for which
we do not have a secret key */
struct {
int op;
int stop_now;
} pipemode;
};
@ -97,6 +101,8 @@ release_list( CTX c )
c->list = NULL;
c->have_data = 0;
c->last_was_session_key = 0;
c->pipemode.op = 0;
c->pipemode.stop_now = 0;
m_free(c->dek); c->dek = NULL;
}
@ -136,6 +142,31 @@ add_gpg_control( CTX c, PACKET *pkt )
* Process the last one and reset everything */
release_list(c);
}
else if ( pkt->pkt.gpg_control->control == 2 ) {
/* Pipemode control packet */
#warning We have to do some sanit checks all over the place
if ( pkt->pkt.gpg_control->datalen < 2 )
log_fatal ("invalid pipemode control packet length\n");
if (pkt->pkt.gpg_control->data[0] == 1) {
/* start the whole thing */
assert ( !c->list ); /* we should be in a pretty virgin state */
assert ( !c->pipemode.op );
c->pipemode.op = pkt->pkt.gpg_control->data[1];
}
else if (pkt->pkt.gpg_control->data[0] == 2) {
/* the signed material follows in a plaintext packet */
assert ( c->pipemode.op == 'B' );
}
else if (pkt->pkt.gpg_control->data[0] == 3) {
assert ( c->pipemode.op == 'B' );
release_list (c);
/* and tell the outer loop to terminate */
c->pipemode.stop_now = 1;
}
else
log_fatal ("invalid pipemode control packet code\n");
return 0; /* no need to store the packet */
}
if( c->list ) /* add another packet */
add_kbnode( c->list, new_kbnode( pkt ));
@ -1094,6 +1125,12 @@ do_proc_packets( CTX c, IOBUF a )
}
else
free_packet(pkt);
if ( c->pipemode.stop_now ) {
/* we won't get an EOF in pipemode, so we have to
* break the loop here */
rc = -1;
break;
}
}
if( rc == G10ERR_INVALID_PACKET )
write_status_text( STATUS_NODATA, "3" );

View file

@ -1796,6 +1796,7 @@ parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen,
* The format of such a control packet is:
* n byte session marker
* 1 byte control type: 1 = Clearsign hash info
* 2 = Pipemode control
* m byte control data
*/

View file

@ -38,12 +38,15 @@
#define CONTROL_PACKET_SPACE 30
#define FAKED_LITERAL_PACKET_SPACE (9+2+2)
enum pipemode_state_e {
STX_init = 0,
STX_wait_operation,
STX_begin,
STX_text,
STX_detached_signature,
STX_signed_data,
STX_wait_init
};
@ -52,6 +55,7 @@ struct pipemode_context_s {
enum pipemode_state_e state;
int operation;
int stop;
int block_mode;
};
@ -89,12 +93,23 @@ pipemode_filter( void *opaque, int control,
if( control == IOBUFCTRL_UNDERFLOW ) {
*ret_len = 0;
/* reserve some space for one control packet */
if ( size <= CONTROL_PACKET_SPACE )
if ( size <= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE )
BUG();
size -= CONTROL_PACKET_SPACE;
size -= CONTROL_PACKET_SPACE+FAKED_LITERAL_PACKET_SPACE;
if ( stx->block_mode ) {
/* reserve 2 bytes for the block length */
buf[n++] = 0;
buf[n++] = 0;
}
while ( n < size ) {
/* FIXME: we have to make sure that we have a large enough
* buffer for a control packet even after we already read
* something. The easest way to do this is probably by ungetting
* the control sequenceand and returning the buffer we have
* already assembled */
int c = iobuf_get (a);
if (c == -1) {
if ( stx->state != STX_init ) {
@ -120,6 +135,7 @@ pipemode_filter( void *opaque, int control,
return -1;
}
stx->state = STX_wait_operation;
stx->block_mode = 0;
break;
case '>': /* end of stream part */
if ( stx->state != STX_wait_init ) {
@ -141,35 +157,64 @@ pipemode_filter( void *opaque, int control,
return -1;
}
stx->operation = c;
stx->state = STX_begin;
n += make_control ( buf, 1, stx->operation );
stx->state = c == 'B'? STX_detached_signature
: STX_begin;
n += make_control ( buf+n, 1, stx->operation );
/* must leave after a control packet */
goto leave;
case 't': /* plaintext text follows */
if ( stx->state != STX_begin ) {
if ( stx->state == STX_detached_signature ) {
if ( stx->operation != 'B' ) {
log_error ("invalid operation for this state\n");
stx->stop = 1;
return -1;
}
stx->state = STX_signed_data;
n += make_control ( buf+n, 2, 'B' );
/* and now we fake a literal data packet much the same
* as in armor.c */
buf[n++] = 0xaf; /* old packet format, type 11,
var length */
buf[n++] = 0; /* set the length header */
buf[n++] = 6;
buf[n++] = 'b'; /* we ignore it anyway */
buf[n++] = 0; /* namelength */
memset(buf+n, 0, 4); /* timestamp */
n += 4;
/* and return now so that we are sure to have
* more space in the bufer for the next control
* packet */
stx->block_mode = 1;
goto leave2;
}
else {
log_error ("invalid state for @t\n");
stx->stop = 1;
return -1;
}
if ( stx->operation != 'E' ) {
log_error ("invalid operation for @t\n");
stx->stop = 1;
return -1;
}
stx->state = STX_text;
n += make_control ( buf, 2, c );
goto leave;
break;
case '.': /* ready */
if ( stx->state == STX_text )
;
if ( stx->state == STX_signed_data ) {
if (stx->block_mode) {
buf[0] = (n-2) >> 8;
buf[1] = (n-2);
if ( buf[0] || buf[1] ) {
/* end of blocks marker */
buf[n++] = 0;
buf[n++] = 0;
}
stx->block_mode = 0;
}
n += make_control ( buf+n, 3, 'B' );
}
else {
log_error ("invalid state for @.\n");
stx->stop = 1;
return -1;
}
stx->state = STX_wait_init;
n += make_control ( buf, 3, c );
goto leave;
default:
@ -191,6 +236,13 @@ pipemode_filter( void *opaque, int control,
stx->stop = 1;
rc = -1; /* eof */
}
if ( stx->block_mode ) {
/* fixup the block length */
buf[0] = (n-2) >> 8;
buf[1] = (n-2);
}
leave2:
log_hexdump ("pipemode:", buf, n );
*ret_len = n;
}
else if( control == IOBUFCTRL_DESC )
@ -211,16 +263,19 @@ run_in_pipemode(void)
memset( &afx, 0, sizeof afx);
memset( &stx, 0, sizeof stx);
/* FIXME: We have to handle de-armoring somehow. We can't rely on
* the standard armor filter becuase it checks only once whether armoring
* is required and it would try to unarmor everything which is not good.
* So, currently only non-armored detached signatures do work.
*/
fp = iobuf_open("-");
iobuf_push_filter (fp, pipemode_filter, &stx );
if( !opt.no_armor )
iobuf_push_filter( fp, armor_filter, &afx );
do {
log_debug ("pipemode: begin proc_packets\n");
write_status (STATUS_BEGIN_STREAM);
rc = proc_packets( NULL, fp );
log_debug ("pipemode: end proc_packets: %s\n", g10_errstr (rc));
write_status (STATUS_END_STREAM);
} while ( !stx.stop );
}
@ -229,3 +284,4 @@ run_in_pipemode(void)

View file

@ -134,6 +134,8 @@ get_status_string ( int no )
case STATUS_NOTATION_NAME : s = "NOTATION_NAME" ; break;
case STATUS_NOTATION_DATA : s = "NOTATION_DATA" ; break;
case STATUS_POLICY_URL : s = "POLICY_URL" ; break;
case STATUS_BEGIN_STREAM : s = "BEGIN_STREAM"; break;
case STATUS_END_STREAM : s = "END_STREAM"; break;
default: s = "?"; break;
}
return s;

View file

@ -85,6 +85,9 @@
#define STATUS_NOTATION_NAME 53
#define STATUS_NOTATION_DATA 54
#define STATUS_POLICY_URL 55
#define STATUS_BEGIN_STREAM 56
#define STATUS_END_STREAM 57
/*-- status.c --*/
void set_status_fd ( int fd );