aboutsummaryrefslogtreecommitdiffstats
path: root/g10/parse-packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/parse-packet.c')
-rw-r--r--g10/parse-packet.c62
1 files changed, 55 insertions, 7 deletions
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 7d5958adf..16332ed24 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -761,9 +761,9 @@ dump_sig_subpkt( int hashed, int type, int critical,
if( 8+n1+n2 != length )
p = "[error]";
else {
- print_string( stdout, s, n1, 0 );
+ print_string( stdout, s, n1, ')' );
putc( '=', stdout );
- print_string( stdout, s+n1, n2, 0 );
+ print_string( stdout, s+n1, n2, ')' );
}
}
}
@@ -788,7 +788,8 @@ dump_sig_subpkt( int hashed, int type, int critical,
p = "primary user id";
break;
case SIGSUBPKT_POLICY:
- p = "policy URL";
+ fputs("policy: ", stdout );
+ print_string( stdout, buffer, length, ')' );
break;
case SIGSUBPKT_KEY_FLAGS:
p = "key flags";
@@ -836,6 +837,7 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
case SIGSUBPKT_PREF_SYM:
case SIGSUBPKT_PREF_HASH:
case SIGSUBPKT_PREF_COMPR:
+ case SIGSUBPKT_POLICY:
return 0;
case SIGSUBPKT_PRIV_ADD_SIG:
/* because we use private data, we check the GNUPG marker */
@@ -849,16 +851,46 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
return -3;
}
+
+static int
+can_handle_critical( const byte *buffer, size_t n, int type )
+{
+ switch( type ) {
+ case SIGSUBPKT_NOTATION:
+ if( n >= 8 && (*buffer & 0x80) )
+ return 1; /* human readable is handled */
+ return 0;
+
+ case SIGSUBPKT_SIG_CREATED:
+ case SIGSUBPKT_SIG_EXPIRE:
+ case SIGSUBPKT_KEY_EXPIRE:
+ case SIGSUBPKT_EXPORTABLE:
+ case SIGSUBPKT_ISSUER:/* issuer key ID */
+ case SIGSUBPKT_PREF_SYM:
+ case SIGSUBPKT_PREF_HASH:
+ case SIGSUBPKT_PREF_COMPR:
+ return 1;
+
+ case SIGSUBPKT_POLICY: /* Is enough to show the policy? */
+ default:
+ return 0;
+ }
+}
+
+
const byte *
-parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
+enum_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype,
+ size_t *ret_n, int *start )
{
int buflen;
int type;
int critical;
int offset;
size_t n;
+ int seq = 0;
+ int reqseq = start? *start: 0;
- if( !buffer )
+ if( !buffer || reqseq == -1 )
return NULL;
buflen = (*buffer << 8) | buffer[1];
buffer += 2;
@@ -889,13 +921,17 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
}
else
critical = 0;
- if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
+ if( !(++seq > reqseq) )
+ ;
+ else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
if( critical ) {
if( n-1 > buflen+1 )
goto too_short;
- if( parse_one_sig_subpkt(buffer+1, n-1, type ) < 0 ) {
+ if( !can_handle_critical(buffer+1, n-1, type ) ) {
log_info(_("subpacket of type %d has critical bit set\n"),
type);
+ if( start )
+ *start = seq;
return NULL; /* this is an error */
}
}
@@ -922,6 +958,8 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
default:
break;
}
+ if( start )
+ *start = seq;
return buffer+offset;
}
buffer += n; buflen -=n;
@@ -929,15 +967,25 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
if( reqtype == SIGSUBPKT_TEST_CRITICAL )
return buffer; /* as value true to indicate that there is no */
/* critical bit we don't understand */
+ if( start )
+ *start = -1;
return NULL; /* end of packets; not found */
too_short:
log_error("buffer shorter than subpacket\n");
+ if( start )
+ *start = -1;
return NULL;
}
const byte *
+parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
+{
+ return enum_sig_subpkt( buffer, reqtype, ret_n, NULL );
+}
+
+const byte *
parse_sig_subpkt2( PKT_signature *sig, sigsubpkttype_t reqtype, size_t *ret_n )
{
const byte *p;