diff options
author | Werner Koch <wk@gnupg.org> | 1999-05-26 14:41:46 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1999-05-26 14:41:46 +0200 |
commit | d5fd04e0ce438d3eaa951566982a0824e48eb1ef (patch) | |
tree | adc1eca7d7eab0d3982ae388be4f592118bf5d7e | |
parent | See ChangeLog: Tue May 25 19:50:32 CEST 1999 Werner Koch (diff) | |
download | gnupg2-d5fd04e0ce438d3eaa951566982a0824e48eb1ef.tar.xz gnupg2-d5fd04e0ce438d3eaa951566982a0824e48eb1ef.zip |
See ChangeLog: Wed May 26 14:36:29 CEST 1999 Werner Koch
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | doc/gpg.1pod | 7 | ||||
-rw-r--r-- | g10/ChangeLog | 13 | ||||
-rw-r--r-- | g10/build-packet.c | 56 | ||||
-rw-r--r-- | g10/g10.c | 40 | ||||
-rw-r--r-- | g10/import.c | 6 | ||||
-rw-r--r-- | g10/mainproc.c | 50 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/packet.h | 10 | ||||
-rw-r--r-- | g10/parse-packet.c | 62 | ||||
-rw-r--r-- | g10/sign.c | 64 |
11 files changed, 234 insertions, 77 deletions
@@ -1,5 +1,5 @@ - * New option -N to insert notations + * New option -N to insert notations and a --set-policy-url. diff --git a/doc/gpg.1pod b/doc/gpg.1pod index 3844977e9..1ad795c37 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -396,6 +396,13 @@ B<--notation-data>, B<-N> I<name>=<value> or the underscore; the first character muts not be a digit. B<value> May be any printable string; it will encoded in UTF8, so sou should have check that your B<--charset> is set right. + If you prefix I<name> with an exclamation mark, the notation + data will be flagged as critical. (rfc2440:5.2.3.15). + +B<--set-policy-url> I<string> + Use I<string> as Policy URL for signatures (rfc2440:5.2.3.19). + If you prefix it with an exclamation mark, the policy URL + packet will be flagged as critical. B<--set-filename> I<string> Use I<string> as the name of file which is stored in diff --git a/g10/ChangeLog b/g10/ChangeLog index ecf7a6853..fafbe61e3 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,16 @@ +Wed May 26 14:36:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * build-packet.c (build_sig_subpkt): Support large packets. + * parse-packet.c (enum_sig_subpkt): Replaces parse_sig_subpkt. + * mainproc.c (print_notation_data): Print all notation packets. + * g10.c (add_notation_data): Add a way to specify the critical flag. + (main): Add option --set-policy-url. + (check_policy_url): Basic checks. + * sign.c (mk_notation_and_policy): Replaces mk_notation. + + * parse-packet.c (can_handle_critical): Moved decision whether we can + handle critical subpacket to an extra function. + Tue May 25 19:50:32 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> * sign.c (sign_file): Always use compression algo 1 for signed diff --git a/g10/build-packet.c b/g10/build-packet.c index 0db12a727..ee19287b1 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -566,6 +566,7 @@ find_subpkt( byte *buffer, sigsubpkttype_t reqtype, return NULL; buflen = (*buffer << 8) | buffer[1]; buffer += 2; + log_debug("find_subpkt: tyoe=%d bufferlength=%d\n", reqtype, buflen ); for(;;) { if( !buflen ) return NULL; /* end of packets; not found */ @@ -586,6 +587,7 @@ find_subpkt( byte *buffer, sigsubpkttype_t reqtype, buffer++; buflen--; } + log_debug("find_subpkt: this len=%u\n", n ); if( buflen < n ) break; type = *buffer & 0x7f; @@ -622,21 +624,29 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, { byte *data; - size_t hlen, dlen; - int found, hashed, realloced; + size_t hlen, dlen, nlen; + int found=0; + int critical, hashed, realloced; size_t n, n0; - if( (data = find_subpkt( sig->hashed_data, type, &hlen, &dlen )) ) + critical = (type & SIGSUBPKT_FLAG_CRITICAL); + type &= ~SIGSUBPKT_FLAG_CRITICAL; + + if( type == SIGSUBPKT_NOTATION ) + ; /* we allow multiple packets */ + else if( (data = find_subpkt( sig->hashed_data, type, &hlen, &dlen )) ) found = 1; else if( (data = find_subpkt( sig->unhashed_data, type, &hlen, &dlen ))) found = 2; - else - found = 0; if( found ) log_bug("build_sig_packet: update nyi\n"); - if( buflen+1 >= 192 ) - log_bug("build_sig_packet: long subpackets are nyi\n"); + if( (buflen+1) >= 8384 ) + nlen = 5; + else if( (buflen+1) >= 192 ) + nlen = 2; + else + nlen = 1; switch( type ) { case SIGSUBPKT_SIG_CREATED: @@ -647,6 +657,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, case SIGSUBPKT_KS_FLAGS: case SIGSUBPKT_KEY_EXPIRE: case SIGSUBPKT_NOTATION: + case SIGSUBPKT_POLICY: hashed = 1; break; default: hashed = 0; break; } @@ -654,7 +665,7 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, if( hashed ) { n0 = sig->hashed_data ? ((*sig->hashed_data << 8) | sig->hashed_data[1]) : 0; - n = n0 + 1 + 1 + buflen; /* length, type, buffer */ + n = n0 + nlen + 1 + buflen; /* length, type, buffer */ realloced = !!sig->hashed_data; data = sig->hashed_data ? m_realloc( sig->hashed_data, n+2 ) : m_alloc( n+2 ); @@ -662,17 +673,37 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, else { n0 = sig->unhashed_data ? ((*sig->unhashed_data << 8) | sig->unhashed_data[1]) : 0; - n = n0 + 1 + 1 + buflen; /* length, type, buffer */ + n = n0 + nlen + 1 + buflen; /* length, type, buffer */ realloced = !!sig->unhashed_data; data = sig->unhashed_data ? m_realloc( sig->unhashed_data, n+2 ) : m_alloc( n+2 ); } + if( critical ) + type |= SIGSUBPKT_FLAG_CRITICAL; + data[0] = (n >> 8) & 0xff; data[1] = n & 0xff; - data[n0+2] = buflen+1; - data[n0+3] = type; - memcpy(data+n0+4, buffer, buflen ); + if( nlen == 5 ) { + data[n0+2] = 255; + data[n0+3] = (buflen+1) >> 24; + data[n0+4] = (buflen+1) >> 16; + data[n0+5] = (buflen+1) >> 8; + data[n0+6] = (buflen+1); + data[n0+7] = type; + memcpy(data+n0+8, buffer, buflen ); + } + else if( nlen == 2 ) { + data[n0+2] = (buflen+1-192) / 256 + 192; + data[n0+3] = (buflen+1-192) & 256; + data[n0+4] = type; + memcpy(data+n0+5, buffer, buflen ); + } + else { + data[n0+2] = buflen+1; + data[n0+3] = type; + memcpy(data+n0+4, buffer, buflen ); + } if( hashed ) { if( !realloced ) @@ -686,7 +717,6 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, } } - /**************** * Put all the required stuff from SIG into subpackets of sig. */ @@ -143,6 +143,7 @@ enum cmd_and_opt_values { aNull = 0, oEmuChecksumBug, oRunAsShmCP, oSetFilename, + oSetPolicyURL, oComment, oThrowKeyid, oForceV3Sigs, @@ -293,6 +294,7 @@ static ARGPARSE_OPTS opts[] = { { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"}, { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" }, { oSetFilename, "set-filename", 2, "@" }, + { oSetPolicyURL, "set-policy-url", 2, "@" }, { oComment, "comment", 2, "@" }, { oNoVersion, "no-version", 0, "@"}, { oNotDashEscaped, "not-dash-escaped", 0, "@" }, @@ -315,6 +317,7 @@ static void set_cmd( enum cmd_and_opt_values *ret_cmd, static void print_hex( byte *p, size_t n ); static void print_mds( const char *fname, int algo ); static void add_notation_data( const char *string ); +static int check_policy_url( const char *s ); const char * strusage( int level ) @@ -709,6 +712,7 @@ main( int argc, char **argv ) #endif break; case oSetFilename: opt.set_filename = pargs.r.ret_str; break; + case oSetPolicyURL: opt.set_policy_url = pargs.r.ret_str; break; case oComment: opt.comment_string = pargs.r.ret_str; break; case oThrowKeyid: opt.throw_keyid = 1; break; case oForceV3Sigs: opt.force_v3_sigs = 1; break; @@ -801,6 +805,10 @@ main( int argc, char **argv ) if( check_digest_algo(opt.s2k_digest_algo) ) log_error(_("selected digest algorithm is invalid\n")); } + if( opt.set_policy_url ) { + if( check_policy_url( opt.set_policy_url ) ) + log_error(_("the given policy URL is invalid\n")); + } if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 ) log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2); if( opt.completes_needed < 1 ) @@ -1394,10 +1402,18 @@ print_mds( const char *fname, int algo ) static void add_notation_data( const char *string ) { - const char *s = string; + const char *s; const char *s2; + STRLIST sl; + int critical=0; int highbit=0; + if( *string == '!' ) { + critical = 1; + string++; + } + s = string; + if( !*s || (*s & 0x80) || (!isalpha(*s) && *s != '_') ) { log_error(_("the first character of a notation name " "must be a letter or an underscore\n") ); @@ -1429,10 +1445,28 @@ add_notation_data( const char *string ) if( highbit ) { /* must use UTF8 encoding */ char *p = native_to_utf8( string ); - add_to_strlist( &opt.notation_data, p ); + sl = add_to_strlist( &opt.notation_data, p ); m_free( p ); } else - add_to_strlist( &opt.notation_data, string ); + sl = add_to_strlist( &opt.notation_data, string ); + + if( critical ) + sl->flags |= 1; +} + + +static int +check_policy_url( const char *s ) +{ + if( *s == '!' ) + s++; + if( !*s ) + return -1; + for(; *s ; s++ ) { + if( (*s & 0x80) || iscntrl(*s) ) + return -1; + } + return 0; } diff --git a/g10/import.c b/g10/import.c index b5fb88af5..060990e36 100644 --- a/g10/import.c +++ b/g10/import.c @@ -376,10 +376,10 @@ import_one( const char *fname, KBNODE keyblock, int fast ) log_info( _("writing to `%s'\n"), keyblock_resource_name(&kbpos) ); if( (rc=lock_keyblock( &kbpos )) ) - log_error(_("can't lock keyring `%': %s\n"), + log_error(_("can't lock keyring `%s': %s\n"), keyblock_resource_name(&kbpos), g10_errstr(rc) ); else if( (rc=insert_keyblock( &kbpos, keyblock )) ) - log_error( _("error writing keyring `%': %s\n"), + log_error( _("error writing keyring `%s': %s\n"), keyblock_resource_name(&kbpos), g10_errstr(rc) ); unlock_keyblock( &kbpos ); /* we are ready */ @@ -432,7 +432,7 @@ import_one( const char *fname, KBNODE keyblock, int fast ) mod_key = 1; /* keyblock_orig has been updated; write */ if( (rc=lock_keyblock( &kbpos )) ) - log_error( _("can't lock keyring `%': %s\n"), + log_error( _("can't lock keyring `%s': %s\n"), keyblock_resource_name(&kbpos), g10_errstr(rc) ); else if( (rc=update_keyblock( &kbpos, keyblock_orig )) ) log_error( _("error writing keyring `%s': %s\n"), diff --git a/g10/mainproc.c b/g10/mainproc.c index 6eb587fe9..3de95e61c 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -497,29 +497,39 @@ print_notation_data( PKT_signature *sig ) { size_t n, n1, n2; const byte *p; + int seq = 0; - /* FIXME: we can not handle multiple notaion data packets yet */ - p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_NOTATION, &n ); - if( !p ) - return; - if( n < 8 ) { - log_info(_("WARNING: invalid notation data found\n")); - return; + while( (p = enum_sig_subpkt( sig->hashed_data, SIGSUBPKT_NOTATION, + &n, &seq )) ) { + if( n < 8 ) { + log_info(_("WARNING: invalid notation data found\n")); + return; + } + if( !(*p & 0x80) ) + return; /* not human readable */ + n1 = (p[4] << 8) | p[5]; + n2 = (p[6] << 8) | p[7]; + p += 8; + if( 8+n1+n2 != n ) { + log_info(_("WARNING: invalid notation data found\n")); + return; + } + log_info(_("Notation: ") ); + print_string( log_stream(), p, n1, 0 ); + putc( '=', log_stream() ); + print_string( log_stream(), p+n1, n2, 0 ); + putc( '\n', log_stream() ); } - if( !(*p & 0x80) ) - return; /* not human readable */ - n1 = (p[4] << 8) | p[5]; - n2 = (p[6] << 8) | p[7]; - p += 8; - if( 8+n1+n2 != n ) { - log_info(_("WARNING: invalid notation data found\n")); - return; + if( (p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_POLICY, &n ) )) { + log_info(_("Policy: ") ); + print_string( log_stream(), p, n, 0 ); + putc( '\n', log_stream() ); } - log_info(_("Notation: ") ); - print_string( log_stream(), p, n1, 0 ); - putc( '=', log_stream() ); - print_string( log_stream(), p+n1, n2, 0 ); - putc( '\n', log_stream() ); + + /* Now check wheter the key of this signature has some + * notation data */ + + /* TODO */ } /**************** diff --git a/g10/options.h b/g10/options.h index 8d3b3c61c..d40f59fb0 100644 --- a/g10/options.h +++ b/g10/options.h @@ -75,6 +75,7 @@ struct { int no_encrypt_to; int interactive; STRLIST notation_data; + const char *set_policy_url; } opt; diff --git a/g10/packet.h b/g10/packet.h index a2af98abb..ac44a4fd3 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -231,7 +231,9 @@ typedef enum { SIGSUBPKT_POLICY =26, /* policy URL */ SIGSUBPKT_KEY_FLAGS =27, /* key flags */ SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */ - SIGSUBPKT_PRIV_ADD_SIG =101 /* signatur is also valid for this uid */ + SIGSUBPKT_PRIV_ADD_SIG =101,/* signatur is also valid for this uid */ + + SIGSUBPKT_FLAG_CRITICAL=128 } sigsubpkttype_t; @@ -264,8 +266,10 @@ int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff ); int skip_some_packets( IOBUF inp, unsigned n ); #endif -const byte *parse_sig_subpkt( const byte *buffer, - sigsubpkttype_t reqtype, size_t *ret_n ); +const byte *enum_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, + size_t *ret_n, int *start ); +const byte *parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, + size_t *ret_n ); const byte *parse_sig_subpkt2( PKT_signature *sig, sigsubpkttype_t reqtype, size_t *ret_n ); 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; diff --git a/g10/sign.c b/g10/sign.c index e62bbbaef..14c63f143 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -46,35 +46,48 @@ * NAME=VALUE format. */ static void -mk_notation( PKT_signature *sig, STRLIST nd ) +mk_notation_and_policy( PKT_signature *sig ) { const char *string, *s; byte *buf; unsigned n1, n2; - if( sig->version < 4 ) { + /* notation data */ + if( opt.notation_data && sig->version < 4 ) log_info("can't put notation data into v3 signatures\n"); - return; + else if( opt.notation_data ) { + STRLIST nd = opt.notation_data; + + for( ; nd; nd = nd->next ) { + string = nd->d; + s = strchr( string, '=' ); + if( !s ) + BUG(); /* we have already parsed this */ + n1 = s - string; + s++; + n2 = strlen(s); + buf = m_alloc( 8 + n1 + n2 ); + buf[0] = 0x80; /* human readable */ + buf[1] = buf[2] = buf[3] = 0; + buf[4] = n1 >> 8; + buf[5] = n1; + buf[6] = n2 >> 8; + buf[7] = n2; + memcpy(buf+8, string, n1 ); + memcpy(buf+8+n1, s, n2 ); + build_sig_subpkt( sig, SIGSUBPKT_NOTATION + | ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0), + buf, 8+n1+n2 ); + } } - for( ; nd; nd = nd->next ) { - string = nd->d; - s = strchr( string, '=' ); - if( !s ) - BUG(); /* we have already parsed this */ - n1 = s - string; - s++; - n2 = strlen(s); - buf = m_alloc( 8 + n1 + n2 ); - buf[0] = 0x80; /* human readable */ - buf[1] = buf[2] = buf[3] = 0; - buf[4] = n1 >> 8; - buf[5] = n1; - buf[6] = n2 >> 8; - buf[7] = n2; - memcpy(buf+8, string, n1 ); - memcpy(buf+8+n1, s, n2 ); - build_sig_subpkt( sig, SIGSUBPKT_NOTATION, buf, 8+n1+n2 ); + /* set policy URL */ + if( (s=opt.set_policy_url) ) { + if( *s == '!' ) + build_sig_subpkt( sig, SIGSUBPKT_POLICY | SIGSUBPKT_FLAG_CRITICAL, + s+1, strlen(s+1) ); + else + build_sig_subpkt( sig, SIGSUBPKT_POLICY, s, strlen(s) ); } } @@ -435,8 +448,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, md_putc( md, sig->version ); } - if( opt.notation_data ) - mk_notation( sig, opt.notation_data ); + mk_notation_and_policy( sig ); md_putc( md, sig->sig_class ); if( sig->version < 4 ) { @@ -625,8 +637,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) md_putc( md, sig->version ); } - if( opt.notation_data ) - mk_notation( sig, opt.notation_data ); + mk_notation_and_policy( sig ); md_putc( md, sig->sig_class ); if( sig->version < 4 ) { @@ -756,8 +767,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, rc = (*mksubpkt)( sig, opaque ); if( !rc ) { - if( opt.notation_data ) - mk_notation( sig, opt.notation_data ); + mk_notation_and_policy( sig ); if( sig->version >= 4 ) md_putc( md, sig->version ); md_putc( md, sig->sig_class ); |