diff options
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r-- | g10/parse-packet.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 3521951b9..ee2ff56eb 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -75,6 +75,8 @@ static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet, int new_ctb); static int parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet, int new_ctb); +static int parse_gpg_control( IOBUF inp, int pkttype, unsigned long pktlen, + PACKET *packet ); static unsigned short read_16(IOBUF inp) @@ -446,6 +448,9 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, case PKT_MDC: rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb ); break; + case PKT_GPG_CONTROL: + rc = parse_gpg_control(inp, pkttype, pktlen, pkt ); + break; default: skip_packet(inp, pkttype, pktlen); break; @@ -1783,3 +1788,66 @@ parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, return 0; } + +/* + * This packet is internally generated by PGG (by armor.c) to + * transfer some information to the lower layer. To make sure that + * this packet is really a GPG faked one and not one comming from outside, + * we first check that tehre is a unique tag in it. + * The format of such a control packet is: + * n byte session marker + * 1 byte control type: 1 = Clearsign hash info + * m byte control data + */ + +static int +parse_gpg_control( IOBUF inp, + int pkttype, unsigned long pktlen, PACKET *packet ) +{ + byte *p; + const byte *sesmark; + size_t sesmarklen; + int i; + + if ( list_mode ) + printf(":packet 63: length %lu ", pktlen); + + sesmark = get_session_marker ( &sesmarklen ); + if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */ + goto skipit; + for( i=0; i < sesmarklen; i++, pktlen-- ) { + if ( sesmark[i] != iobuf_get_noeof(inp) ) + goto skipit; + } + if ( list_mode ) + puts ("- gpg control packet"); + + packet->pkt.gpg_control = m_alloc(sizeof *packet->pkt.gpg_control + + pktlen - 1); + packet->pkt.gpg_control->control = iobuf_get_noeof(inp); pktlen--; + packet->pkt.gpg_control->datalen = pktlen; + p = packet->pkt.gpg_control->data; + for( ; pktlen; pktlen--, p++ ) + *p = iobuf_get_noeof(inp); + + return 0; + + skipit: + if ( list_mode ) { + int c, i=0 ; + printf("- private (rest length %lu)\n", pktlen); + if( iobuf_in_block_mode(inp) ) { + while( (c=iobuf_get(inp)) != -1 ) + dump_hex_line(c, &i); + } + else { + for( ; pktlen; pktlen-- ) + dump_hex_line(iobuf_get(inp), &i); + } + putchar('\n'); + } + skip_rest(inp,pktlen); + return G10ERR_INVALID_PACKET; +} + + |