mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +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:
parent
fcfc223dbb
commit
4dcdaa3b1b
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
35
g10/getkey.c
35
g10/getkey.c
@ -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 ********************
|
||||
|
@ -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 );
|
||||
|
138
g10/keygen.c
138
g10/keygen.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 --*/
|
||||
|
@ -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,
|
||||
|
@ -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 ) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user