1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-05 20:48:52 +01:00

* main.h, keygen.c (keygen_add_revkey): Add revocation key subpackets to a

signature (callable by make_keysig_packet). (write_direct_sig): Write a 1F
direct key signature. (parse_revocation_key): Parse a string in
algo:fpr:sensitive format into a revocation key. (get_parameter_revkey,
do_generate_keypair): Call above functions when prompted from a batch key
generation file.

* build-packet.c (build_sig_subpkt): Allow multiple revocation key
subpackets in a single sig.

* keydb.h, getkey.c (get_seckey_byfprint): Same as get_pubkey_byfprint,
except for secret keys.  We only know the fingerprint of a revocation key,
so this is needed to retrieve the secret key needed to issue a revokation.

* packet.h, parse-packet.c (parse_signature, parse_revkeys): Split revkey
parsing off into a new function that can be used to reparse after
manipulating the revkey list.

* sign.c (make_keysig_packet): Ability to make 1F direct key signatures.
This commit is contained in:
David Shaw 2002-05-16 03:35:55 +00:00
parent fcfc223dbb
commit 4dcdaa3b1b
9 changed files with 232 additions and 27 deletions

View File

@ -1,3 +1,28 @@
2002-05-16 David Shaw <dshaw@jabberwocky.com>
* main.h, keygen.c (keygen_add_revkey): Add revocation key
subpackets to a signature (callable by
make_keysig_packet). (write_direct_sig): Write a 1F direct key
signature. (parse_revocation_key): Parse a string in
algo:fpr:sensitive format into a revocation
key. (get_parameter_revkey, do_generate_keypair): Call above
functions when prompted from a batch key generation file.
* build-packet.c (build_sig_subpkt): Allow multiple revocation key
subpackets in a single sig.
* keydb.h, getkey.c (get_seckey_byfprint): Same as
get_pubkey_byfprint, except for secret keys. We only know the
fingerprint of a revocation key, so this is needed to retrieve the
secret key needed to issue a revokation.
* packet.h, parse-packet.c (parse_signature, parse_revkeys): Split
revkey parsing off into a new function that can be used to reparse
after manipulating the revkey list.
* sign.c (make_keysig_packet): Ability to make 1F direct key
signatures.
2002-05-15 David Shaw <dshaw@jabberwocky.com>
* options.skel: keyserver.pgp.com is gone, so list pgp.surfnet.nl

View File

@ -710,6 +710,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
{
case SIGSUBPKT_NOTATION:
case SIGSUBPKT_POLICY:
case SIGSUBPKT_REV_KEY:
/* we do allow multiple subpackets */
break;

View File

@ -963,6 +963,41 @@ get_seckey_end( GETKEY_CTX ctx )
}
/****************
* Search for a key with the given fingerprint.
* FIXME:
* We should replace this with the _byname function. Thiscsan be done
* by creating a userID conforming to the unified fingerprint style.
*/
int
get_seckey_byfprint( PKT_secret_key *sk,
const byte *fprint, size_t fprint_len)
{
int rc;
if( fprint_len == 20 || fprint_len == 16 ) {
struct getkey_ctx_s ctx;
KBNODE kb = NULL;
memset( &ctx, 0, sizeof ctx );
ctx.exact = 1 ;
ctx.not_allocated = 1;
ctx.kr_handle = keydb_new (1);
ctx.nitems = 1;
ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
: KEYDB_SEARCH_MODE_FPR20;
memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
rc = lookup( &ctx, &kb, 1 );
if (!rc && sk )
sk_from_block ( &ctx, sk, kb );
release_kbnode ( kb );
get_pubkey_end( &ctx );
}
else
rc = G10ERR_GENERAL; /* Oops */
return rc;
}
/************************************************
************* Merging stuff ********************

View File

@ -206,6 +206,8 @@ int seckey_available( u32 *keyid );
int get_seckey_byname( PKT_secret_key *sk, const char *name, int unlock );
int get_seckey_bynames( GETKEY_CTX *rx, PKT_secret_key *sk,
STRLIST names, KBNODE *ret_keyblock );
int get_seckey_byfprint( PKT_secret_key *sk,
const byte *fprint, size_t fprint_len);
int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
void get_seckey_end( GETKEY_CTX ctx );
int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );

View File

@ -50,6 +50,7 @@ enum para_name {
pNAMEEMAIL,
pNAMECOMMENT,
pPREFERENCES,
pREVOKER,
pUSERID,
pEXPIREDATE,
pKEYEXPIRE, /* in n seconds */
@ -68,6 +69,7 @@ struct para_data_s {
STRING2KEY *s2k;
u32 expire;
unsigned int usage;
struct revocation_key revkey;
char value[1];
} u;
};
@ -383,6 +385,68 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
return 0;
}
int
keygen_add_revkey(PKT_signature *sig, void *opaque)
{
struct revocation_key *revkey=opaque;
byte buf[2+MAX_FINGERPRINT_LEN];
buf[0]=revkey->class;
buf[1]=revkey->algid;
memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN);
build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN);
sig->revkey=m_realloc(sig->revkey,
sizeof(struct revocation_key *)*(sig->numrevkeys+1));
/* All sigs with revocation keys set are nonrevocable */
sig->flags.revocable=0;
buf[0] = 0;
build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
parse_revkeys(sig);
return 0;
}
static int
write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
struct revocation_key *revkey )
{
PACKET *pkt;
PKT_signature *sig;
int rc=0;
KBNODE node;
PKT_public_key *pk;
if( opt.verbose )
log_info(_("writing direct signature\n"));
/* get the pk packet from the pub_tree */
node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
if( !node )
BUG();
pk = node->pkt->pkt.public_key;
/* we have to cache the key, so that the verification of the signature
* creation is able to retrieve the public key */
cache_public_key (pk);
/* and make the signature */
rc = make_keysig_packet(&sig,pk,NULL,NULL,sk,0x1F,0,0,0,0,
keygen_add_revkey,revkey);
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
return rc;
}
pkt = m_alloc_clear( sizeof *pkt );
pkt->pkttype = PKT_SIGNATURE;
pkt->pkt.signature = sig;
add_kbnode( root, new_kbnode( pkt ) );
return rc;
}
static int
write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
@ -1385,6 +1449,59 @@ parse_parameter_usage (const char *fname,
return 0;
}
static int
parse_revocation_key (const char *fname,
struct para_data_s *para, enum para_name key)
{
struct para_data_s *r = get_parameter( para, key );
struct revocation_key revkey;
char *pn;
int i;
if( !r )
return 0; /* none (this is an optional parameter) */
pn = r->u.value;
revkey.class=0x80;
revkey.algid=atoi(pn);
if(!revkey.algid)
goto fail;
/* Skip to the fpr */
while(*pn && *pn!=':')
pn++;
if(*pn!=':')
goto fail;
pn++;
for(i=0;i<MAX_FINGERPRINT_LEN && *pn;i++,pn+=2)
{
int c=hextobyte(pn);
if(c==-1)
goto fail;
revkey.fpr[i]=c;
}
/* skip to the tag */
while(*pn && *pn!='s' && *pn!='S')
pn++;
if(ascii_strcasecmp(pn,"sensitive")==0)
revkey.class|=0x40;
memcpy(&r->u.revkey,&revkey,sizeof(struct revocation_key));
return 0;
fail:
log_error("%s:%d: invalid revocation key\n", fname, r->lnr );
return -1; /* error */
}
static u32
get_parameter_u32( struct para_data_s *para, enum para_name key )
@ -1421,6 +1538,12 @@ get_parameter_s2k( struct para_data_s *para, enum para_name key )
return r? r->u.s2k : NULL;
}
static struct revocation_key *
get_parameter_revkey( struct para_data_s *para, enum para_name key )
{
struct para_data_s *r = get_parameter( para, key );
return r? &r->u.revkey : NULL;
}
static int
proc_parameter_file( struct para_data_s *para, const char *fname,
@ -1478,6 +1601,10 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
/* Set preferences, if any. */
keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ));
/* Set revoker, if any. */
if (parse_revocation_key (fname, para, pREVOKER))
return -1;
/* make DEK and S2K from the Passphrase */
r = get_parameter( para, pPASSPHRASE );
if( r && *r->u.value ) {
@ -1559,6 +1686,7 @@ read_parameter_file( const char *fname )
{ "Expire-Date", pEXPIREDATE },
{ "Passphrase", pPASSPHRASE },
{ "Preferences", pPREFERENCES },
{ "Revoker", pREVOKER },
{ NULL, 0 }
};
FILE *fp;
@ -1845,6 +1973,7 @@ do_generate_keypair( struct para_data_s *para,
KBNODE sec_root = NULL;
PKT_secret_key *sk = NULL;
const char *s;
struct revocation_key *revkey;
int rc;
int did_sub = 0;
@ -1917,6 +2046,14 @@ do_generate_keypair( struct para_data_s *para,
get_parameter_s2k( para, pPASSPHRASE_S2K ),
&sk,
get_parameter_u32( para, pKEYEXPIRE ) );
if(!rc && (revkey=get_parameter_revkey(para,pREVOKER)))
{
rc=write_direct_sig(pub_root,pub_root,sk,revkey);
if(!rc)
write_direct_sig(sec_root,pub_root,sk,revkey);
}
if( !rc && (s=get_parameter_value(para, pUSERID)) ) {
write_uid(pub_root, s );
if( !rc )
@ -2170,4 +2307,3 @@ write_keyblock( IOBUF out, KBNODE node )
}
return 0;
}

View File

@ -117,6 +117,7 @@ char *keygen_get_std_prefs (void);
int keygen_add_key_expire( 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_add_revkey(PKT_signature *sig, void *opaque);
int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
/*-- openfile.c --*/

View File

@ -394,6 +394,7 @@ const byte *parse_sig_subpkt ( const subpktarea_t *buffer,
const byte *parse_sig_subpkt2 ( PKT_signature *sig,
sigsubpkttype_t reqtype,
size_t *ret_n );
void parse_revkeys(PKT_signature *sig);
int parse_attribute_subpkts(PKT_user_id *uid);
void make_attribute_uidname(PKT_user_id *uid);
PACKET *create_gpg_control ( ctrlpkttype_t type,

View File

@ -1121,6 +1121,31 @@ parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
return p;
}
/* Find all revocation keys. Look in hashed area only. */
void parse_revkeys(PKT_signature *sig)
{
struct revocation_key *revkey;
int seq=0;
size_t len;
if(sig->sig_class!=0x1F)
return;
while((revkey=
(struct revocation_key *)enum_sig_subpkt(sig->hashed,
SIGSUBPKT_REV_KEY,
&len,&seq)))
{
if(len==sizeof(struct revocation_key) &&
(revkey->class&0x80)) /* 0x80 bit must be set */
{
sig->revkey=m_realloc(sig->revkey,
sizeof(struct revocation_key *)*(sig->numrevkeys+1));
sig->revkey[sig->numrevkeys]=revkey;
sig->numrevkeys++;
}
}
}
static int
parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
@ -1261,28 +1286,9 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
if(p && *p==0)
sig->flags.exportable=0;
/* Find all revocation keys. Back to hashed area only. */
/* Find all revocation keys. */
if(sig->sig_class==0x1F)
{
struct revocation_key *revkey;
int seq=0;
size_t len;
while((revkey=
(struct revocation_key *)enum_sig_subpkt(sig->hashed,
SIGSUBPKT_REV_KEY,
&len,&seq)))
{
if(len==sizeof(struct revocation_key) &&
(revkey->class&0x80)) /* 0x80 bit must be set */
{
sig->revkey=m_realloc(sig->revkey,
sizeof(struct revocation_key *)*(sig->numrevkeys+1));
sig->revkey[sig->numrevkeys]=revkey;
sig->numrevkeys++;
}
}
}
parse_revkeys(sig);
}
if( list_mode ) {

View File

@ -1097,7 +1097,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
int rc=0;
MD_HANDLE md;
assert( (sigclass >= 0x10 && sigclass <= 0x13)
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
|| sigclass == 0x20 || sigclass == 0x18
|| sigclass == 0x30 || sigclass == 0x28 );
@ -1140,7 +1140,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/
hash_public_key( md, subpk );
}
else if( sigclass != 0x20 ) {
else if( sigclass != 0x1F && sigclass != 0x20 ) {
hash_uid (md, sigversion, uid);
}
/* and make the signature packet */
@ -1241,5 +1241,3 @@ update_keysig_packet( PKT_signature **ret_sig,
*ret_sig = sig;
return rc;
}