1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-05 12:31:50 +01:00

* options.h, sign.c (mk_notation_policy_etc), gpg.c (add_notation_data):

Use it here for the various notation commands.

* packet.h, main.h, keygen.c (keygen_add_notations), build-packet.c
(string_to_notation, sig_to_notation) (free_notation): New "one stop
shopping" functions to handle notations and start removing some code
duplication.
This commit is contained in:
David Shaw 2006-03-08 23:30:12 +00:00
parent 90d8377276
commit 4fea8fdbbb
9 changed files with 275 additions and 117 deletions

View File

@ -1,3 +1,14 @@
2006-03-08 David Shaw <dshaw@jabberwocky.com>
* options.h, sign.c (mk_notation_policy_etc), gpg.c
(add_notation_data): Use it here for the various notation
commands.
* packet.h, main.h, keygen.c (keygen_add_notations),
build-packet.c (string_to_notation, sig_to_notation)
(free_notation): New "one stop shopping" functions to handle
notations and start removing some code duplication.
2006-03-07 David Shaw <dshaw@jabberwocky.com> 2006-03-07 David Shaw <dshaw@jabberwocky.com>
* options.h, mainproc.c (check_sig_and_print), gpg.c (main): * options.h, mainproc.c (check_sig_and_print), gpg.c (main):

View File

@ -1,6 +1,6 @@
/* build-packet.c - assemble packets and write them /* build-packet.c - assemble packets and write them
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -25,6 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <ctype.h>
#include "packet.h" #include "packet.h"
#include "errors.h" #include "errors.h"
@ -33,6 +34,7 @@
#include "util.h" #include "util.h"
#include "cipher.h" #include "cipher.h"
#include "memory.h" #include "memory.h"
#include "i18n.h"
#include "options.h" #include "options.h"
static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ); static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
@ -886,6 +888,153 @@ build_attribute_subpkt(PKT_user_id *uid,byte type,
uid->attrib_len+=idx+headerlen+buflen; uid->attrib_len+=idx+headerlen+buflen;
} }
struct notation *
string_to_notation(const char *string,int is_utf8)
{
const char *s,*i;
int saw_at=0,highbit=0;
struct notation *notation;
notation=xmalloc_clear(sizeof(*notation));
if(*string=='!')
{
notation->flags.critical=1;
string++;
}
/* If and when the IETF assigns some official name tags, we'll have
to add them here. */
for( s=string ; *s != '='; s++ )
{
if( *s=='@')
saw_at++;
if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
{
log_error(_("a notation name must have only printable characters"
" or spaces, and end with an '='\n") );
goto fail;
}
}
notation->name=xmalloc((s-string)+1);
strncpy(notation->name,string,s-string);
notation->name[s-string]='\0';
if(!saw_at && !opt.expert)
{
log_error(_("a user notation name must contain the '@' character\n"));
goto fail;
}
if (saw_at > 1)
{
log_error(_("a notation name must not contain more than"
" one '@' character\n"));
goto fail;
}
i=s+1;
/* we only support printable text - therefore we enforce the use of
only printable characters (an empty value is valid) */
for(s++; *s ; s++ )
{
if ( !isascii (*s) )
highbit=1;
else if (iscntrl(*s))
{
log_error(_("a notation value must not use any"
" control characters\n"));
goto fail;
}
}
if(!highbit || is_utf8)
notation->value=xstrdup(i);
else
notation->value=native_to_utf8(i);
return notation;
fail:
free_notation(notation);
return NULL;
}
struct notation *
sig_to_notation(PKT_signature *sig)
{
const byte *p;
size_t len;
int seq=0,crit;
struct notation *list=NULL;
while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
{
int n1,n2;
struct notation *n=NULL;
if(len<8)
{
log_info(_("WARNING: invalid notation data found\n"));
continue;
}
n1=(p[4]<<8)|p[5];
n2=(p[6]<<8)|p[7];
if(8+n1+n2!=len)
{
log_info(_("WARNING: invalid notation data found\n"));
continue;
}
n=xmalloc_clear(sizeof(*n));
n->name=xmalloc(n1+1);
memcpy(n->name,&p[8],n1);
n->name[n1]='\0';
if(p[0]&0x80)
{
n->value=xmalloc(n2+1);
memcpy(n->value,&p[8+n1],n2);
n->value[n2]='\0';
}
else
{
n->value=xmalloc(2+strlen(_("not human readable"))+2+1);
strcpy(n->value,"[ ");
strcat(n->value,_("not human readable"));
strcat(n->value," ]");
}
n->flags.critical=crit;
n->next=list;
list=n;
}
return list;
}
void
free_notation(struct notation *notation)
{
while(notation)
{
struct notation *n=notation;
xfree(n->name);
xfree(n->value);
notation=n->next;
xfree(n);
}
}
static int static int
do_signature( IOBUF out, int ctb, PKT_signature *sig ) do_signature( IOBUF out, int ctb, PKT_signature *sig )
{ {

View File

@ -3974,69 +3974,22 @@ print_mds( const char *fname, int algo )
static void static void
add_notation_data( const char *string, int which ) add_notation_data( const char *string, int which )
{ {
const char *s; struct notation *notation;
STRLIST sl,*notation_data;
int critical=0;
int highbit=0;
int saw_at=0;
if(which) notation=string_to_notation(string,utf8_strings);
notation_data=&opt.cert_notation_data; if(notation)
else {
notation_data=&opt.sig_notation_data; if(which)
{
if( *string == '!' ) { notation->next=opt.cert_notations;
critical = 1; opt.cert_notations=notation;
string++; }
} else
{
/* If and when the IETF assigns some official name tags, we'll notation->next=opt.sig_notations;
have to add them here. */ opt.sig_notations=notation;
for( s=string ; *s != '='; s++ )
{
if( *s=='@')
saw_at++;
if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
{
log_error(_("a notation name must have only printable characters "
"or spaces, and end with an '='\n") );
return;
}
}
if(!saw_at && !opt.expert)
{
log_error(_("a user notation name must contain the '@' character\n"));
return;
}
if (saw_at > 1)
{
log_error(_("a notation name must not contain more than "
"one '@' character\n"));
return;
}
/* we only support printable text - therefore we enforce the use
* of only printable characters (an empty value is valid) */
for( s++; *s ; s++ ) {
if ( !isascii (*s) )
highbit = 1;
else if (iscntrl(*s)) {
log_error(_("a notation value must not use"
" any control characters\n") );
return;
} }
} }
if( highbit ) /* must use UTF8 encoding */
sl = add_to_strlist2( notation_data, string, utf8_strings );
else
sl = add_to_strlist( notation_data, string );
if( critical )
sl->flags |= 1;
} }
static void static void

View File

@ -1,6 +1,6 @@
/* keyedit.c - keyedit stuff /* keyedit.c - keyedit stuff
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -546,7 +546,7 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
byte trust_depth=0,trust_value=0; byte trust_depth=0,trust_value=0;
if(local || nonrevocable || trust || if(local || nonrevocable || trust ||
opt.cert_policy_url || opt.cert_notation_data) opt.cert_policy_url || opt.cert_notations)
force_v4=1; force_v4=1;
/* we have to use a copy of the sk, because make_keysig_packet /* we have to use a copy of the sk, because make_keysig_packet

View File

@ -1,6 +1,6 @@
/* keygen.c - generate a key pair /* keygen.c - generate a key pair
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -689,6 +689,50 @@ keygen_add_keyserver_url(PKT_signature *sig, void *opaque)
return 0; return 0;
} }
int
keygen_add_notations(PKT_signature *sig,void *opaque)
{
struct notation *notation;
/* We always start clean */
delete_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION);
delete_sig_subpkt(sig->unhashed,SIGSUBPKT_NOTATION);
sig->flags.notation=0;
for(notation=opaque;notation;notation=notation->next)
if(!notation->flags.ignore)
{
unsigned char *buf;
unsigned int n1,n2;
n1=strlen(notation->name);
if(notation->altvalue)
n2=strlen(notation->altvalue);
else
n2=strlen(notation->value);
buf = xmalloc( 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, notation->name, n1 );
if(notation->altvalue)
memcpy(buf+8+n1, notation->altvalue, n2 );
else
memcpy(buf+8+n1, notation->value, n2 );
build_sig_subpkt( sig, SIGSUBPKT_NOTATION |
(notation->flags.critical?SIGSUBPKT_FLAG_CRITICAL:0),
buf, 8+n1+n2 );
xfree(buf);
}
return 0;
}
int int
keygen_add_revkey(PKT_signature *sig, void *opaque) keygen_add_revkey(PKT_signature *sig, void *opaque)
{ {

View File

@ -1,6 +1,6 @@
/* main.h /* main.h
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -55,7 +55,7 @@ struct groupitem
struct groupitem *next; struct groupitem *next;
}; };
/*-- g10.c --*/ /*-- gpg.c --*/
extern int g10_errors_seen; extern int g10_errors_seen;
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
@ -181,6 +181,7 @@ int keygen_add_key_expire( PKT_signature *sig, void *opaque );
int keygen_add_std_prefs( PKT_signature *sig, void *opaque ); int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ); int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
int keygen_add_keyserver_url(PKT_signature *sig, void *opaque); int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
int keygen_add_notations(PKT_signature *sig,void *opaque);
int keygen_add_revkey(PKT_signature *sig, void *opaque); int keygen_add_revkey(PKT_signature *sig, void *opaque);
int make_backsig(PKT_signature *sig,PKT_public_key *pk, int make_backsig(PKT_signature *sig,PKT_public_key *pk,
PKT_public_key *sub_pk,PKT_secret_key *sub_sk); PKT_public_key *sub_pk,PKT_secret_key *sub_sk);

View File

@ -163,8 +163,8 @@ struct
char *temp_dir; char *temp_dir;
int no_encrypt_to; int no_encrypt_to;
int interactive; int interactive;
STRLIST sig_notation_data; struct notation *sig_notations;
STRLIST cert_notation_data; struct notation *cert_notations;
STRLIST sig_policy_url; STRLIST sig_policy_url;
STRLIST cert_policy_url; STRLIST cert_policy_url;
STRLIST sig_keyserver_url; STRLIST sig_keyserver_url;

View File

@ -1,6 +1,6 @@
/* packet.h - packet definitions /* packet.h - packet definitions
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2004 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -407,6 +407,18 @@ typedef enum {
SIGSUBPKT_FLAG_CRITICAL=128 SIGSUBPKT_FLAG_CRITICAL=128
} sigsubpkttype_t; } sigsubpkttype_t;
struct notation
{
char *name;
char *value;
char *altvalue;
struct
{
unsigned int critical:1;
unsigned int ignore:1;
} flags;
struct notation *next;
};
/*-- mainproc.c --*/ /*-- mainproc.c --*/
int proc_packets( void *ctx, IOBUF a ); int proc_packets( void *ctx, IOBUF a );
@ -476,6 +488,9 @@ int delete_sig_subpkt(subpktarea_t *buffer, sigsubpkttype_t type );
void build_attribute_subpkt(PKT_user_id *uid,byte type, void build_attribute_subpkt(PKT_user_id *uid,byte type,
const void *buf,u32 buflen, const void *buf,u32 buflen,
const void *header,u32 headerlen); const void *header,u32 headerlen);
struct notation *string_to_notation(const char *string,int is_utf8);
struct notation *sig_to_notation(PKT_signature *sig);
void free_notation(struct notation *notation);
/*-- free-packet.c --*/ /*-- free-packet.c --*/
void free_symkey_enc( PKT_symkey_enc *enc ); void free_symkey_enc( PKT_symkey_enc *enc );

View File

@ -1,6 +1,6 @@
/* sign.c - sign data /* sign.c - sign data
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
* 2005 Free Software Foundation, Inc. * 2006 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -55,9 +55,9 @@ void __stdcall Sleep(ulong);
static int recipient_digest_algo=0; static int recipient_digest_algo=0;
/**************** /****************
* Create a notation. It is assumed that the stings in STRLIST * Create notations and other stuff. It is assumed that the stings in
* are already checked to contain only printable data and have a valid * STRLIST are already checked to contain only printable data and have
* NAME=VALUE format. * a valid NAME=VALUE format.
*/ */
static void static void
mk_notation_policy_etc( PKT_signature *sig, mk_notation_policy_etc( PKT_signature *sig,
@ -65,9 +65,8 @@ mk_notation_policy_etc( PKT_signature *sig,
{ {
const char *string; const char *string;
char *s=NULL; char *s=NULL;
byte *buf; STRLIST pu=NULL;
unsigned n1, n2; struct notation *nd=NULL;
STRLIST nd=NULL,pu=NULL;
struct expando_args args; struct expando_args args;
memset(&args,0,sizeof(args)); memset(&args,0,sizeof(args));
@ -80,57 +79,43 @@ mk_notation_policy_etc( PKT_signature *sig,
good to do these checks anyway. */ good to do these checks anyway. */
/* notation data */ /* notation data */
if(IS_SIG(sig) && opt.sig_notation_data) if(IS_SIG(sig) && opt.sig_notations)
{ {
if(sig->version<4) if(sig->version<4)
log_error(_("can't put notation data into v3 (PGP 2.x style) " log_error(_("can't put notation data into v3 (PGP 2.x style) "
"signatures\n")); "signatures\n"));
else else
nd=opt.sig_notation_data; nd=opt.sig_notations;
} }
else if( IS_CERT(sig) && opt.cert_notation_data ) else if( IS_CERT(sig) && opt.cert_notations )
{ {
if(sig->version<4) if(sig->version<4)
log_error(_("can't put notation data into v3 (PGP 2.x style) " log_error(_("can't put notation data into v3 (PGP 2.x style) "
"key signatures\n")); "key signatures\n"));
else else
nd=opt.cert_notation_data; nd=opt.cert_notations;
} }
for( ; nd; nd = nd->next ) { if(nd)
char *expanded; {
struct notation *i;
string = nd->d; for(i=nd;i;i=i->next)
s = strchr( string, '=' );
if( !s )
BUG(); /* we have already parsed this */
n1 = s - string;
s++;
expanded=pct_expando(s,&args);
if(!expanded)
{ {
log_error(_("WARNING: unable to %%-expand notation " i->altvalue=pct_expando(i->value,&args);
"(too large). Using unexpanded.\n")); if(!i->altvalue)
expanded=xstrdup(s); log_error(_("WARNING: unable to %%-expand notation "
"(too large). Using unexpanded.\n"));
} }
n2 = strlen(expanded); keygen_add_notations(sig,nd);
buf = xmalloc( 8 + n1 + n2 );
buf[0] = 0x80; /* human readable */ for(i=nd;i;i=i->next)
buf[1] = buf[2] = buf[3] = 0; {
buf[4] = n1 >> 8; xfree(i->altvalue);
buf[5] = n1; i->altvalue=NULL;
buf[6] = n2 >> 8; }
buf[7] = n2; }
memcpy(buf+8, string, n1 );
memcpy(buf+8+n1, expanded, n2 );
build_sig_subpkt( sig, SIGSUBPKT_NOTATION
| ((nd->flags & 1)? SIGSUBPKT_FLAG_CRITICAL:0),
buf, 8+n1+n2 );
xfree(expanded);
xfree(buf);
}
/* set policy URL */ /* set policy URL */
if( IS_SIG(sig) && opt.sig_policy_url ) if( IS_SIG(sig) && opt.sig_policy_url )
@ -650,7 +635,7 @@ write_signature_packets (SK_LIST sk_list, IOBUF out, MD_HANDLE hash,
if(opt.force_v3_sigs || RFC1991) if(opt.force_v3_sigs || RFC1991)
sig->version=3; sig->version=3;
else if(duration || opt.sig_policy_url else if(duration || opt.sig_policy_url
|| opt.sig_notation_data || opt.sig_keyserver_url) || opt.sig_notations || opt.sig_keyserver_url)
sig->version=4; sig->version=4;
else else
sig->version=sk->version; sig->version=sk->version;