summaryrefslogtreecommitdiffstats
path: root/g10/parse-packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r--g10/parse-packet.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 76e1a7a35..14d4c7b1c 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -197,7 +197,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
{
int rc, c, ctb, pkttype, lenbytes;
unsigned long pktlen;
- byte hdr[5];
+ byte hdr[8];
int hdrlen;
int pgp3 = 0;
@@ -233,8 +233,17 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
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) );
+ return G10ERR_INVALID_PACKET;
+ }
+ pktlen |= (hdr[hdrlen++] = c );
+ }
else { /* partial body length */
- pktlen = 1 << (c & 0x1f);
log_debug("partial body length of %lu bytes\n", pktlen );
iobuf_set_partial_block_mode(inp, pktlen);
pktlen = 0;/* to indicate partial length */
@@ -543,20 +552,32 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
}
-static const byte *
-parse_subpkt( const byte *buffer, int reqtype )
+const byte *
+parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
{
- int buflen = (*buffer << 8) | buffer[1];
+ int buflen;
int type;
int critical;
size_t n;
+ if( !buffer )
+ return NULL;
+ buflen = (*buffer << 8) | buffer[1];
buffer += 2;
for(;;) {
if( !buflen )
return NULL; /* end of packets; not found */
n = *buffer++; buflen--;
- if( n >= 192 ) {
+ if( n == 255 ) {
+ if( buflen < 4 )
+ goto too_short;
+ n = (buffer[0] << 24) | (buffer[1] << 16)
+ | (buffer[2] << 8) | buffer[3];
+ buffer += 4;
+ buflen -= 4;
+
+ }
+ else if( n >= 192 ) {
if( buflen < 2 )
goto too_short;
n = (( n - 192 ) << 8) + *buffer + 192;
@@ -573,27 +594,27 @@ parse_subpkt( const byte *buffer, int reqtype )
critical = 0;
if( reqtype < 0 ) { /* list packets */
printf("\t%ssubpacket %d of length %u (%s)\n",
- reqtype == -1 ? "hashed ":"", type, (unsigned)n,
- type == 2 ? "signature creation time"
- : type == 3 ? "signature expiration time"
- : type == 4 ? "exportable"
- : type == 5 ? "trust signature"
- : type == 6 ? "regular expression"
- : type == 7 ? "revocable"
- : type == 9 ? "key expiration time"
- : type ==10 ? "additional recipient request"
- : type ==11 ? "preferred symmetric algorithms"
- : type ==12 ? "revocation key"
- : type ==16 ? "issuer key ID"
- : type ==20 ? "notation data"
- : type ==21 ? "preferred hash algorithms"
- : type ==22 ? "preferred compression algorithms"
- : type ==23 ? "key server preferences"
- : type ==24 ? "preferred key server"
- : type ==25 ? "primary user id"
- : type ==26 ? "policy URL"
- : type ==27 ? "key flags"
- : type ==28 ? "signer's user id"
+ reqtype == SIGSUBPKT_LIST_HASHED ? "hashed ":"", type, (unsigned)n,
+ type == SIGSUBPKT_SIG_CREATED ? "signature creation time"
+ : type == SIGSUBPKT_SIG_EXPIRE ? "signature expiration time"
+ : type == SIGSUBPKT_EXPORTABLE ? "exportable"
+ : type == SIGSUBPKT_TRUST ? "trust signature"
+ : type == SIGSUBPKT_REGEXP ? "regular expression"
+ : type == SIGSUBPKT_REVOCABLE ? "revocable"
+ : type == SIGSUBPKT_KEY_EXPIRE ? "key expiration time"
+ : type == SIGSUBPKT_ARR ? "additional recipient request"
+ : type == SIGSUBPKT_PREF_SYM ? "preferred symmetric algorithms"
+ : type == SIGSUBPKT_REV_KEY ? "revocation key"
+ : type == SIGSUBPKT_ISSUER ? "issuer key ID"
+ : type == SIGSUBPKT_NOTATION ? "notation data"
+ : type == SIGSUBPKT_PREF_HASH ? "preferred hash algorithms"
+ : type == SIGSUBPKT_PREF_COMPR ? "preferred compression algorithms"
+ : type == SIGSUBPKT_KS_FLAGS ? "key server preferences"
+ : type == SIGSUBPKT_PREF_KS ? "preferred key server"
+ : type == SIGSUBPKT_PRIMARY_UID ? "primary user id"
+ : type == SIGSUBPKT_POLICY ? "policy URL"
+ : type == SIGSUBPKT_KEY_FLAGS ? "key flags"
+ : type == SIGSUBPKT_SIGNERS_UID ? "signer's user id"
: "?");
}
else if( type == reqtype )
@@ -604,29 +625,17 @@ parse_subpkt( const byte *buffer, int reqtype )
n--;
if( n > buflen )
goto too_short;
+ if( ret_n )
+ *ret_n = n;
switch( type ) {
- case 2: /* signature creation time */
+ case SIGSUBPKT_SIG_CREATED:
if( n < 4 )
break;
return buffer;
- case 16:/* issuer key ID */
+ case SIGSUBPKT_ISSUER:/* issuer key ID */
if( n < 8 )
break;
return buffer;
- case 3: /* signature expiration time */
- case 4: /* exportable */
- case 5: /* trust signature */
- case 6: /* regular expression */
- case 7: /* revocable */
- case 9: /* key expiration time */
- case 10:/* additional recipient request */
- case 11:/* preferred symmetric algorithms */
- case 12:/* revocation key */
- case 20:/* notation data */
- case 21:/* preferred hash algorithms */
- case 22:/* preferred compression algorithms */
- case 23:/* key server preferences */
- case 24:/* preferred key server */
default: BUG(); /* not yet needed */
}
log_error("subpacket of type %d too short\n", type);
@@ -718,12 +727,12 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
if( is_v4 ) { /*extract required information */
const byte *p;
- p = parse_subpkt( sig->hashed_data, 2 );
+ p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_SIG_CREATED, NULL );
if( !p )
log_error("signature packet without timestamp\n");
else
sig->timestamp = buffer_to_u32(p);
- p = parse_subpkt( sig->unhashed_data, 16 );
+ p = parse_sig_subpkt( sig->unhashed_data, SIGSUBPKT_ISSUER, NULL );
if( !p )
log_error("signature packet without keyid\n");
else {
@@ -742,8 +751,8 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
sig->digest_algo,
sig->digest_start[0], sig->digest_start[1] );
if( is_v4 ) {
- parse_subpkt( sig->hashed_data, -1 );
- parse_subpkt( sig->unhashed_data, -2 );
+ parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_LIST_HASHED, NULL );
+ parse_sig_subpkt( sig->unhashed_data,SIGSUBPKT_LIST_UNHASHED, NULL);
}
}
if( is_ELGAMAL(sig->pubkey_algo) ) {