mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-10 13:04:23 +01:00
* keygen.c (gen_elg, gen_dsa, gen_rsa, do_create, do_generate_keypair,
generate_subkeypair): New is_subkey argument to set whether a generated key is a subkey. Do not overload the ret_sk. This is some early cleanup to do backsigs for signing subkeys. * keygen.c (write_keybinding, do_generate_keypair, generate_subkeypair): Keep track of the unprotected subkey secret key so we can make a backsig with it. * keygen.c (make_backsig): New function to add a backsig to a binding sig of signing subkeys. Currently disabled. (write_keybinding): Call it here, for signing subkeys only. * sign.c (make_keysig_packet): Allow generating 0x19 signatures (same as 0x18 or 0x28, but used for backsigs). * packet.h, build-packet.c (build_sig_subpkt): Add new SIGSUBPKT_SIGNATURE type for embedded signatures.
This commit is contained in:
parent
0a17966a21
commit
4420275b83
@ -1,5 +1,25 @@
|
|||||||
2004-04-16 David Shaw <dshaw@jabberwocky.com>
|
2004-04-16 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* keygen.c (gen_elg, gen_dsa, gen_rsa, do_create,
|
||||||
|
do_generate_keypair, generate_subkeypair): New is_subkey argument
|
||||||
|
to set whether a generated key is a subkey. Do not overload the
|
||||||
|
ret_sk. This is some early cleanup to do backsigs for signing
|
||||||
|
subkeys.
|
||||||
|
|
||||||
|
* keygen.c (write_keybinding, do_generate_keypair,
|
||||||
|
generate_subkeypair): Keep track of the unprotected subkey secret
|
||||||
|
key so we can make a backsig with it.
|
||||||
|
|
||||||
|
* keygen.c (make_backsig): New function to add a backsig to a
|
||||||
|
binding sig of signing subkeys. Currently disabled.
|
||||||
|
(write_keybinding): Call it here, for signing subkeys only.
|
||||||
|
|
||||||
|
* sign.c (make_keysig_packet): Allow generating 0x19 signatures
|
||||||
|
(same as 0x18 or 0x28, but used for backsigs).
|
||||||
|
|
||||||
|
* packet.h, build-packet.c (build_sig_subpkt): Add new
|
||||||
|
SIGSUBPKT_SIGNATURE type for embedded signatures.
|
||||||
|
|
||||||
* main.h, misc.c (optsep, argsplit, optlen, parse_options):
|
* main.h, misc.c (optsep, argsplit, optlen, parse_options):
|
||||||
Simplify code and properly handle a partial match against an
|
Simplify code and properly handle a partial match against an
|
||||||
option with an argument.
|
option with an argument.
|
||||||
|
@ -656,6 +656,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
|||||||
case SIGSUBPKT_NOTATION:
|
case SIGSUBPKT_NOTATION:
|
||||||
case SIGSUBPKT_POLICY:
|
case SIGSUBPKT_POLICY:
|
||||||
case SIGSUBPKT_REV_KEY:
|
case SIGSUBPKT_REV_KEY:
|
||||||
|
case SIGSUBPKT_SIGNATURE:
|
||||||
/* we do allow multiple subpackets */
|
/* we do allow multiple subpackets */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -725,12 +726,14 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
|
|||||||
else
|
else
|
||||||
nlen = 1; /* just a 1 byte length header */
|
nlen = 1; /* just a 1 byte length header */
|
||||||
|
|
||||||
switch( type ) {
|
switch( type )
|
||||||
|
{
|
||||||
/* The issuer being unhashed is a historical oddity. It
|
/* The issuer being unhashed is a historical oddity. It
|
||||||
should work equally as well hashed. Of course, if even an
|
should work equally as well hashed. Of course, if even an
|
||||||
unhashed issuer is tampered with, it makes it awfully hard
|
unhashed issuer is tampered with, it makes it awfully hard
|
||||||
to verify the sig... */
|
to verify the sig... */
|
||||||
case SIGSUBPKT_ISSUER:
|
case SIGSUBPKT_ISSUER:
|
||||||
|
case SIGSUBPKT_SIGNATURE:
|
||||||
hashed = 0;
|
hashed = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
221
g10/keygen.c
221
g10/keygen.c
@ -623,6 +623,98 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
make_backsig(PKT_signature *sig, PKT_public_key *pk,
|
||||||
|
PKT_public_key *sub_pk, PKT_secret_key *sub_sk)
|
||||||
|
{
|
||||||
|
PKT_signature *backsig;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* This is not enabled yet, as I want to get a bit closer to RFC day
|
||||||
|
before enabling this. I've been burned before :) */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cache_public_key (sub_pk);
|
||||||
|
|
||||||
|
rc=make_keysig_packet(&backsig,pk,NULL,sub_pk,sub_sk, 0x19, 0, 0, 0, 0,
|
||||||
|
NULL,NULL);
|
||||||
|
if( rc )
|
||||||
|
log_error("make_keysig_packet failed for backsig: %s\n", g10_errstr(rc) );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* get it into a binary packed form. */
|
||||||
|
IOBUF backsig_out=iobuf_temp();
|
||||||
|
PACKET backsig_pkt;
|
||||||
|
byte *buf;
|
||||||
|
size_t pktlen=0;
|
||||||
|
|
||||||
|
init_packet(&backsig_pkt);
|
||||||
|
backsig_pkt.pkttype=PKT_SIGNATURE;
|
||||||
|
backsig_pkt.pkt.signature=backsig;
|
||||||
|
build_packet(backsig_out,&backsig_pkt);
|
||||||
|
free_packet(&backsig_pkt);
|
||||||
|
buf=iobuf_get_temp_buffer(backsig_out);
|
||||||
|
|
||||||
|
/* Remove the packet header */
|
||||||
|
if(buf[0]&0x40)
|
||||||
|
{
|
||||||
|
if(buf[1]<192)
|
||||||
|
{
|
||||||
|
pktlen=buf[1];
|
||||||
|
buf+=2;
|
||||||
|
}
|
||||||
|
else if(buf[1]<224)
|
||||||
|
{
|
||||||
|
pktlen=(buf[1]-192)*256;
|
||||||
|
pktlen+=buf[2]+192;
|
||||||
|
buf+=3;
|
||||||
|
}
|
||||||
|
else if(buf[1]==255)
|
||||||
|
{
|
||||||
|
pktlen =buf[2] << 24;
|
||||||
|
pktlen|=buf[3] << 16;
|
||||||
|
pktlen|=buf[4] << 8;
|
||||||
|
pktlen|=buf[5];
|
||||||
|
buf+=6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int mark=1;
|
||||||
|
|
||||||
|
switch(buf[0]&3)
|
||||||
|
{
|
||||||
|
case 3:
|
||||||
|
BUG();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
pktlen =buf[mark++] << 24;
|
||||||
|
pktlen|=buf[mark++] << 16;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
pktlen|=buf[mark++] << 8;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
pktlen|=buf[mark++];
|
||||||
|
}
|
||||||
|
|
||||||
|
buf+=mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now make the binary blob into a subpacket */
|
||||||
|
build_sig_subpkt(sig,SIGSUBPKT_SIGNATURE,buf,pktlen);
|
||||||
|
|
||||||
|
iobuf_close(backsig_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
write_direct_sig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
||||||
struct revocation_key *revkey )
|
struct revocation_key *revkey )
|
||||||
@ -705,15 +797,17 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sub_sk is currently unused (reserved for backsigs) */
|
||||||
static int
|
static int
|
||||||
write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
write_keybinding( KBNODE root, KBNODE pub_root,
|
||||||
|
PKT_secret_key *pri_sk, PKT_secret_key *sub_sk,
|
||||||
unsigned int use )
|
unsigned int use )
|
||||||
{
|
{
|
||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
PKT_signature *sig;
|
PKT_signature *sig;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
PKT_public_key *pk, *subpk;
|
PKT_public_key *pri_pk, *sub_pk;
|
||||||
struct opaque_data_usage_and_pk oduap;
|
struct opaque_data_usage_and_pk oduap;
|
||||||
|
|
||||||
if( opt.verbose )
|
if( opt.verbose )
|
||||||
@ -723,30 +817,38 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
|||||||
node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
|
node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
|
||||||
if( !node )
|
if( !node )
|
||||||
BUG();
|
BUG();
|
||||||
pk = node->pkt->pkt.public_key;
|
pri_pk = node->pkt->pkt.public_key;
|
||||||
/* we have to cache the key, so that the verification of the signature
|
/* we have to cache the key, so that the verification of the signature
|
||||||
* creation is able to retrieve the public key */
|
* creation is able to retrieve the public key */
|
||||||
cache_public_key (pk);
|
cache_public_key (pri_pk);
|
||||||
|
|
||||||
/* find the last subkey */
|
/* find the last subkey */
|
||||||
subpk = NULL;
|
sub_pk = NULL;
|
||||||
for(node=pub_root; node; node = node->next ) {
|
for(node=pub_root; node; node = node->next ) {
|
||||||
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
|
||||||
subpk = node->pkt->pkt.public_key;
|
sub_pk = node->pkt->pkt.public_key;
|
||||||
}
|
}
|
||||||
if( !subpk )
|
if( !sub_pk )
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* and make the signature */
|
/* and make the signature */
|
||||||
oduap.usage = use;
|
oduap.usage = use;
|
||||||
oduap.pk = subpk;
|
oduap.pk = sub_pk;
|
||||||
rc = make_keysig_packet( &sig, pk, NULL, subpk, sk, 0x18, 0, 0, 0, 0,
|
rc=make_keysig_packet(&sig, pri_pk, NULL, sub_pk, pri_sk, 0x18, 0, 0, 0, 0,
|
||||||
keygen_add_key_flags_and_expire, &oduap );
|
keygen_add_key_flags_and_expire, &oduap );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make a backsig */
|
||||||
|
if(use&PUBKEY_USAGE_SIG)
|
||||||
|
{
|
||||||
|
rc=make_backsig(sig,pri_pk,sub_pk,sub_sk);
|
||||||
|
if(rc)
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
pkt = m_alloc_clear( sizeof *pkt );
|
pkt = m_alloc_clear( sizeof *pkt );
|
||||||
pkt->pkttype = PKT_SIGNATURE;
|
pkt->pkttype = PKT_SIGNATURE;
|
||||||
pkt->pkt.signature = sig;
|
pkt->pkt.signature = sig;
|
||||||
@ -757,7 +859,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
|
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval, int is_subkey)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
@ -804,7 +906,7 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
sk->protect.algo = 0;
|
sk->protect.algo = 0;
|
||||||
|
|
||||||
sk->csum = checksum_mpi( sk->skey[3] );
|
sk->csum = checksum_mpi( sk->skey[3] );
|
||||||
if( ret_sk ) /* not a subkey: return an unprotected version of the sk */
|
if( ret_sk ) /* return an unprotected version of the sk */
|
||||||
*ret_sk = copy_secret_key( NULL, sk );
|
*ret_sk = copy_secret_key( NULL, sk );
|
||||||
|
|
||||||
if( dek ) {
|
if( dek ) {
|
||||||
@ -820,14 +922,14 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
|
||||||
pkt->pkt.public_key = pk;
|
pkt->pkt.public_key = pk;
|
||||||
add_kbnode(pub_root, new_kbnode( pkt ));
|
add_kbnode(pub_root, new_kbnode( pkt ));
|
||||||
|
|
||||||
/* don't know whether it makes sense to have the factors, so for now
|
/* don't know whether it makes sense to have the factors, so for now
|
||||||
* we store them in the secret keyring (but they are not secret) */
|
* we store them in the secret keyring (but they are not secret) */
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
|
||||||
pkt->pkt.secret_key = sk;
|
pkt->pkt.secret_key = sk;
|
||||||
add_kbnode(sec_root, new_kbnode( pkt ));
|
add_kbnode(sec_root, new_kbnode( pkt ));
|
||||||
for(i=0; factors[i]; i++ )
|
for(i=0; factors[i]; i++ )
|
||||||
@ -843,7 +945,7 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
|
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval, int is_subkey)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
@ -890,7 +992,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
sk->protect.algo = 0;
|
sk->protect.algo = 0;
|
||||||
|
|
||||||
sk->csum = checksum_mpi ( sk->skey[4] );
|
sk->csum = checksum_mpi ( sk->skey[4] );
|
||||||
if( ret_sk ) /* not a subkey: return an unprotected version of the sk */
|
if( ret_sk ) /* return an unprotected version of the sk */
|
||||||
*ret_sk = copy_secret_key( NULL, sk );
|
*ret_sk = copy_secret_key( NULL, sk );
|
||||||
|
|
||||||
if( dek ) {
|
if( dek ) {
|
||||||
@ -906,7 +1008,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
|
||||||
pkt->pkt.public_key = pk;
|
pkt->pkt.public_key = pk;
|
||||||
add_kbnode(pub_root, new_kbnode( pkt ));
|
add_kbnode(pub_root, new_kbnode( pkt ));
|
||||||
|
|
||||||
@ -917,7 +1019,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
* are known.
|
* are known.
|
||||||
*/
|
*/
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
|
||||||
pkt->pkt.secret_key = sk;
|
pkt->pkt.secret_key = sk;
|
||||||
add_kbnode(sec_root, new_kbnode( pkt ));
|
add_kbnode(sec_root, new_kbnode( pkt ));
|
||||||
for(i=1; factors[i]; i++ ) /* the first one is q */
|
for(i=1; factors[i]; i++ ) /* the first one is q */
|
||||||
@ -933,7 +1035,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||||
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
|
STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval, int is_subkey)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
@ -983,7 +1085,7 @@ gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
sk->csum += checksum_mpi (sk->skey[3] );
|
sk->csum += checksum_mpi (sk->skey[3] );
|
||||||
sk->csum += checksum_mpi (sk->skey[4] );
|
sk->csum += checksum_mpi (sk->skey[4] );
|
||||||
sk->csum += checksum_mpi (sk->skey[5] );
|
sk->csum += checksum_mpi (sk->skey[5] );
|
||||||
if( ret_sk ) /* not a subkey: return an unprotected version of the sk */
|
if( ret_sk ) /* return an unprotected version of the sk */
|
||||||
*ret_sk = copy_secret_key( NULL, sk );
|
*ret_sk = copy_secret_key( NULL, sk );
|
||||||
|
|
||||||
if( dek ) {
|
if( dek ) {
|
||||||
@ -999,12 +1101,12 @@ gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
|
||||||
pkt->pkt.public_key = pk;
|
pkt->pkt.public_key = pk;
|
||||||
add_kbnode(pub_root, new_kbnode( pkt ));
|
add_kbnode(pub_root, new_kbnode( pkt ));
|
||||||
|
|
||||||
pkt = m_alloc_clear(sizeof *pkt);
|
pkt = m_alloc_clear(sizeof *pkt);
|
||||||
pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
|
pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
|
||||||
pkt->pkt.secret_key = sk;
|
pkt->pkt.secret_key = sk;
|
||||||
add_kbnode(sec_root, new_kbnode( pkt ));
|
add_kbnode(sec_root, new_kbnode( pkt ));
|
||||||
|
|
||||||
@ -1517,7 +1619,8 @@ do_ask_passphrase( STRING2KEY **ret_s2k )
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
|
do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
|
||||||
DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate )
|
DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 expiredate,
|
||||||
|
int is_subkey )
|
||||||
{
|
{
|
||||||
int rc=0;
|
int rc=0;
|
||||||
|
|
||||||
@ -1529,11 +1632,14 @@ do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
|
|||||||
"generator a better chance to gain enough entropy.\n") );
|
"generator a better chance to gain enough entropy.\n") );
|
||||||
|
|
||||||
if( algo == PUBKEY_ALGO_ELGAMAL_E )
|
if( algo == PUBKEY_ALGO_ELGAMAL_E )
|
||||||
rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
|
rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate,
|
||||||
|
is_subkey);
|
||||||
else if( algo == PUBKEY_ALGO_DSA )
|
else if( algo == PUBKEY_ALGO_DSA )
|
||||||
rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
|
rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate,
|
||||||
|
is_subkey);
|
||||||
else if( algo == PUBKEY_ALGO_RSA )
|
else if( algo == PUBKEY_ALGO_RSA )
|
||||||
rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
|
rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate,
|
||||||
|
is_subkey);
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
@ -2264,7 +2370,7 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
{
|
{
|
||||||
KBNODE pub_root = NULL;
|
KBNODE pub_root = NULL;
|
||||||
KBNODE sec_root = NULL;
|
KBNODE sec_root = NULL;
|
||||||
PKT_secret_key *sk = NULL;
|
PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
|
||||||
const char *s;
|
const char *s;
|
||||||
struct revocation_key *revkey;
|
struct revocation_key *revkey;
|
||||||
int rc;
|
int rc;
|
||||||
@ -2343,8 +2449,8 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
pub_root, sec_root,
|
pub_root, sec_root,
|
||||||
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
||||||
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
||||||
&sk,
|
&pri_sk,
|
||||||
get_parameter_u32( para, pKEYEXPIRE ) );
|
get_parameter_u32( para, pKEYEXPIRE ), 0 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2352,16 +2458,16 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
get_parameter_u32 (para, pKEYEXPIRE), para);
|
get_parameter_u32 (para, pKEYEXPIRE), para);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
sk = sec_root->next->pkt->pkt.secret_key;
|
pri_sk = sec_root->next->pkt->pkt.secret_key;
|
||||||
assert (sk);
|
assert (pri_sk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!rc && (revkey=get_parameter_revkey(para,pREVOKER)))
|
if(!rc && (revkey=get_parameter_revkey(para,pREVOKER)))
|
||||||
{
|
{
|
||||||
rc=write_direct_sig(pub_root,pub_root,sk,revkey);
|
rc=write_direct_sig(pub_root,pub_root,pri_sk,revkey);
|
||||||
if(!rc)
|
if(!rc)
|
||||||
write_direct_sig(sec_root,pub_root,sk,revkey);
|
write_direct_sig(sec_root,pub_root,pri_sk,revkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !rc && (s=get_parameter_value(para, pUSERID)) ) {
|
if( !rc && (s=get_parameter_value(para, pUSERID)) ) {
|
||||||
@ -2369,10 +2475,10 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
if( !rc )
|
if( !rc )
|
||||||
write_uid(sec_root, s );
|
write_uid(sec_root, s );
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_selfsig(pub_root, pub_root, sk,
|
rc = write_selfsig(pub_root, pub_root, pri_sk,
|
||||||
get_parameter_uint (para, pKEYUSAGE));
|
get_parameter_uint (para, pKEYUSAGE));
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_selfsig(sec_root, pub_root, sk,
|
rc = write_selfsig(sec_root, pub_root, pri_sk,
|
||||||
get_parameter_uint (para, pKEYUSAGE));
|
get_parameter_uint (para, pKEYUSAGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2385,8 +2491,8 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
pub_root, sec_root,
|
pub_root, sec_root,
|
||||||
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
get_parameter_dek( para, pPASSPHRASE_DEK ),
|
||||||
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
get_parameter_s2k( para, pPASSPHRASE_S2K ),
|
||||||
NULL,
|
&sub_sk,
|
||||||
get_parameter_u32( para, pSUBKEYEXPIRE ) );
|
get_parameter_u32( para, pSUBKEYEXPIRE ), 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2395,10 +2501,10 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_keybinding(pub_root, pub_root, sk,
|
rc = write_keybinding(pub_root, pub_root, pri_sk, sub_sk,
|
||||||
get_parameter_uint (para, pSUBKEYUSAGE));
|
get_parameter_uint (para, pSUBKEYUSAGE));
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_keybinding(sec_root, pub_root, sk,
|
rc = write_keybinding(sec_root, pub_root, pri_sk, sub_sk,
|
||||||
get_parameter_uint (para, pSUBKEYUSAGE));
|
get_parameter_uint (para, pSUBKEYUSAGE));
|
||||||
did_sub = 1;
|
did_sub = 1;
|
||||||
}
|
}
|
||||||
@ -2409,9 +2515,9 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
get_parameter_u32 (para, pKEYEXPIRE), para);
|
get_parameter_u32 (para, pKEYEXPIRE), para);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = write_keybinding (pub_root, pub_root, sk, PUBKEY_USAGE_AUTH);
|
rc = write_keybinding (pub_root, pub_root, pri_sk, sub_sk, PUBKEY_USAGE_AUTH);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = write_keybinding (sec_root, pub_root, sk, PUBKEY_USAGE_AUTH);
|
rc = write_keybinding (sec_root, pub_root, pri_sk, sub_sk, PUBKEY_USAGE_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !rc && outctrl->use_files ) { /* direct write to specified files */
|
if( !rc && outctrl->use_files ) { /* direct write to specified files */
|
||||||
@ -2518,8 +2624,11 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
}
|
}
|
||||||
release_kbnode( pub_root );
|
release_kbnode( pub_root );
|
||||||
release_kbnode( sec_root );
|
release_kbnode( sec_root );
|
||||||
if( sk && !card) /* the unprotected secret key unless we have a */
|
|
||||||
free_secret_key(sk); /* shallow copy in card mode. */
|
if( pri_sk && !card) /* the unprotected secret key unless we have a */
|
||||||
|
free_secret_key(pri_sk); /* shallow copy in card mode. */
|
||||||
|
if( sub_sk )
|
||||||
|
free_secret_key(sub_sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2532,7 +2641,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
{
|
{
|
||||||
int okay=0, rc=0;
|
int okay=0, rc=0;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
PKT_secret_key *sk = NULL; /* this is the primary sk */
|
PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
|
||||||
int algo;
|
int algo;
|
||||||
unsigned int use;
|
unsigned int use;
|
||||||
u32 expire;
|
u32 expire;
|
||||||
@ -2550,11 +2659,11 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* make a copy of the sk to keep the protected one in the keyblock */
|
/* make a copy of the sk to keep the protected one in the keyblock */
|
||||||
sk = copy_secret_key( NULL, node->pkt->pkt.secret_key );
|
pri_sk = copy_secret_key( NULL, node->pkt->pkt.secret_key );
|
||||||
|
|
||||||
cur_time = make_timestamp();
|
cur_time = make_timestamp();
|
||||||
if( sk->timestamp > cur_time ) {
|
if( pri_sk->timestamp > cur_time ) {
|
||||||
ulong d = sk->timestamp - cur_time;
|
ulong d = pri_sk->timestamp - cur_time;
|
||||||
log_info( d==1 ? _("key has been created %lu second "
|
log_info( d==1 ? _("key has been created %lu second "
|
||||||
"in future (time warp or clock problem)\n")
|
"in future (time warp or clock problem)\n")
|
||||||
: _("key has been created %lu seconds "
|
: _("key has been created %lu seconds "
|
||||||
@ -2565,14 +2674,14 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk->version < 4) {
|
if (pri_sk->version < 4) {
|
||||||
log_info (_("NOTE: creating subkeys for v3 keys "
|
log_info (_("NOTE: creating subkeys for v3 keys "
|
||||||
"is not OpenPGP compliant\n"));
|
"is not OpenPGP compliant\n"));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unprotect to get the passphrase */
|
/* unprotect to get the passphrase */
|
||||||
switch( is_secret_key_protected( sk ) ) {
|
switch( is_secret_key_protected( pri_sk ) ) {
|
||||||
case -1:
|
case -1:
|
||||||
rc = G10ERR_PUBKEY_ALGO;
|
rc = G10ERR_PUBKEY_ALGO;
|
||||||
break;
|
break;
|
||||||
@ -2581,7 +2690,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tty_printf("Key is protected.\n");
|
tty_printf("Key is protected.\n");
|
||||||
rc = check_secret_key( sk, 0 );
|
rc = check_secret_key( pri_sk, 0 );
|
||||||
if( !rc )
|
if( !rc )
|
||||||
passphrase = get_last_passphrase();
|
passphrase = get_last_passphrase();
|
||||||
break;
|
break;
|
||||||
@ -2589,7 +2698,6 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
if( rc )
|
if( rc )
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
|
||||||
algo = ask_algo( 1, &use );
|
algo = ask_algo( 1, &use );
|
||||||
assert(algo);
|
assert(algo);
|
||||||
nbits = ask_keysize( algo );
|
nbits = ask_keysize( algo );
|
||||||
@ -2608,11 +2716,11 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
|
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
|
||||||
dek, s2k, NULL, expire );
|
dek, s2k, &sub_sk, expire, 1 );
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_keybinding(pub_keyblock, pub_keyblock, sk, use);
|
rc = write_keybinding(pub_keyblock, pub_keyblock, pri_sk, sub_sk, use);
|
||||||
if( !rc )
|
if( !rc )
|
||||||
rc = write_keybinding(sec_keyblock, pub_keyblock, sk, use);
|
rc = write_keybinding(sec_keyblock, pub_keyblock, pri_sk, sub_sk, use);
|
||||||
if( !rc ) {
|
if( !rc ) {
|
||||||
okay = 1;
|
okay = 1;
|
||||||
write_status_text (STATUS_KEY_CREATED, "S");
|
write_status_text (STATUS_KEY_CREATED, "S");
|
||||||
@ -2624,8 +2732,11 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
|
|||||||
m_free( passphrase );
|
m_free( passphrase );
|
||||||
m_free( dek );
|
m_free( dek );
|
||||||
m_free( s2k );
|
m_free( s2k );
|
||||||
if( sk ) /* release the copy of the (now unprotected) secret key */
|
/* release the copy of the (now unprotected) secret keys */
|
||||||
free_secret_key(sk);
|
if( pri_sk )
|
||||||
|
free_secret_key(pri_sk);
|
||||||
|
if( sub_sk )
|
||||||
|
free_secret_key(sub_sk);
|
||||||
set_next_passphrase( NULL );
|
set_next_passphrase( NULL );
|
||||||
return okay;
|
return okay;
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,7 @@ typedef enum {
|
|||||||
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
|
SIGSUBPKT_SIGNERS_UID =28, /* signer's user id */
|
||||||
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
SIGSUBPKT_REVOC_REASON =29, /* reason for revocation */
|
||||||
SIGSUBPKT_FEATURES =30, /* feature flags */
|
SIGSUBPKT_FEATURES =30, /* feature flags */
|
||||||
|
SIGSUBPKT_SIGNATURE =32, /* embedded signature */
|
||||||
|
|
||||||
SIGSUBPKT_FLAG_CRITICAL=128
|
SIGSUBPKT_FLAG_CRITICAL=128
|
||||||
} sigsubpkttype_t;
|
} sigsubpkttype_t;
|
||||||
|
16
g10/sign.c
16
g10/sign.c
@ -1245,7 +1245,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
MD_HANDLE md;
|
MD_HANDLE md;
|
||||||
|
|
||||||
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
|
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x1F
|
||||||
|| sigclass == 0x20 || sigclass == 0x18
|
|| sigclass == 0x20 || sigclass == 0x18 || sigclass == 0x19
|
||||||
|| sigclass == 0x30 || sigclass == 0x28 );
|
|| sigclass == 0x30 || sigclass == 0x28 );
|
||||||
|
|
||||||
if (opt.force_v4_certs)
|
if (opt.force_v4_certs)
|
||||||
@ -1284,12 +1284,17 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
|
|||||||
|
|
||||||
md = md_open( digest_algo, 0 );
|
md = md_open( digest_algo, 0 );
|
||||||
|
|
||||||
/* hash the public key certificate and the user id */
|
/* hash the public key certificate */
|
||||||
hash_public_key( md, pk );
|
hash_public_key( md, pk );
|
||||||
if( sigclass == 0x18 || sigclass == 0x28 ) { /* subkey binding/revocation*/
|
|
||||||
|
if( sigclass == 0x18 || sigclass == 0x19 || sigclass == 0x28 )
|
||||||
|
{
|
||||||
|
/* hash the subkey binding/backsig/revocation */
|
||||||
hash_public_key( md, subpk );
|
hash_public_key( md, subpk );
|
||||||
}
|
}
|
||||||
else if( sigclass != 0x1F && sigclass != 0x20 ) {
|
else if( sigclass != 0x1F && sigclass != 0x20 )
|
||||||
|
{
|
||||||
|
/* hash the user id */
|
||||||
hash_uid (md, sigversion, uid);
|
hash_uid (md, sigversion, uid);
|
||||||
}
|
}
|
||||||
/* and make the signature packet */
|
/* and make the signature packet */
|
||||||
@ -1347,8 +1352,7 @@ update_keysig_packet( PKT_signature **ret_sig,
|
|||||||
PKT_public_key *subpk,
|
PKT_public_key *subpk,
|
||||||
PKT_secret_key *sk,
|
PKT_secret_key *sk,
|
||||||
int (*mksubpkt)(PKT_signature *, void *),
|
int (*mksubpkt)(PKT_signature *, void *),
|
||||||
void *opaque
|
void *opaque )
|
||||||
)
|
|
||||||
{
|
{
|
||||||
PKT_signature *sig;
|
PKT_signature *sig;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user