mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
g10: Support primary key generation by keygrip.
* g10/keygen.c (para_name): Add pKEYGRIP. (generate_keypair): Use pKEYGRIP for key generation. (do_generate_keypair): Call do_create_from_keygrip with pKEYGRIP. -- https://lists.gnupg.org/pipermail/gnupg-devel/2017-February/032591.html Reported-by: Alon Bar-Lev <alon.barlev@gmail.com> Suggested-by: Peter Lebbing <peter@digitalbrains.com> Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
a022baa4a4
commit
3fc69224b7
272
g10/keygen.c
272
g10/keygen.c
@ -89,7 +89,8 @@ enum para_name {
|
|||||||
pSERIALNO,
|
pSERIALNO,
|
||||||
pCARDBACKUPKEY,
|
pCARDBACKUPKEY,
|
||||||
pHANDLE,
|
pHANDLE,
|
||||||
pKEYSERVER
|
pKEYSERVER,
|
||||||
|
pKEYGRIP
|
||||||
};
|
};
|
||||||
|
|
||||||
struct para_data_s {
|
struct para_data_s {
|
||||||
@ -3653,8 +3654,9 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
|
|||||||
{ "Preferences", pPREFERENCES },
|
{ "Preferences", pPREFERENCES },
|
||||||
{ "Revoker", pREVOKER },
|
{ "Revoker", pREVOKER },
|
||||||
{ "Handle", pHANDLE },
|
{ "Handle", pHANDLE },
|
||||||
{ "Keyserver", pKEYSERVER },
|
{ "Keyserver", pKEYSERVER },
|
||||||
{ NULL, 0 }
|
{ "Keygrip", pKEYGRIP },
|
||||||
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
IOBUF fp;
|
IOBUF fp;
|
||||||
byte *line;
|
byte *line;
|
||||||
@ -4175,103 +4177,14 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
else if (full) /* Full featured key generation. */
|
else if (full) /* Full featured key generation. */
|
||||||
{
|
{
|
||||||
int subkey_algo;
|
int subkey_algo;
|
||||||
char *curve = NULL;
|
char *key_from_hexgrip = NULL;
|
||||||
|
|
||||||
/* Fixme: To support creating a primary key by keygrip we better
|
algo = ask_algo (ctrl, 0, &subkey_algo, &use, &key_from_hexgrip);
|
||||||
also define the keyword for the parameter file. Note that
|
if (key_from_hexgrip)
|
||||||
the subkey case will never be asserted if a keygrip has been
|
|
||||||
given. */
|
|
||||||
algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL);
|
|
||||||
if (subkey_algo)
|
|
||||||
{
|
{
|
||||||
/* Create primary and subkey at once. */
|
|
||||||
both = 1;
|
|
||||||
if (algo == PUBKEY_ALGO_ECDSA
|
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|
||||||
{
|
|
||||||
curve = ask_curve (&algo, &subkey_algo);
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pKEYTYPE;
|
|
||||||
sprintf( r->u.value, "%d", algo);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
nbits = 0;
|
|
||||||
r = xmalloc_clear (sizeof *r + strlen (curve));
|
|
||||||
r->key = pKEYCURVE;
|
|
||||||
strcpy (r->u.value, curve);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pKEYTYPE;
|
|
||||||
sprintf( r->u.value, "%d", algo);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
nbits = ask_keysize (algo, 0);
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pKEYLENGTH;
|
|
||||||
sprintf( r->u.value, "%u", nbits);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
}
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pKEYUSAGE;
|
|
||||||
strcpy( r->u.value, "sign" );
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pSUBKEYTYPE;
|
|
||||||
sprintf( r->u.value, "%d", subkey_algo);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = pSUBKEYUSAGE;
|
|
||||||
strcpy( r->u.value, "encrypt" );
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
|
|
||||||
if (algo == PUBKEY_ALGO_ECDSA
|
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|
||||||
{
|
|
||||||
if (algo == PUBKEY_ALGO_EDDSA
|
|
||||||
&& subkey_algo == PUBKEY_ALGO_ECDH)
|
|
||||||
{
|
|
||||||
/* Need to switch to a different curve for the
|
|
||||||
encryption key. */
|
|
||||||
xfree (curve);
|
|
||||||
curve = xstrdup ("Curve25519");
|
|
||||||
}
|
|
||||||
r = xmalloc_clear (sizeof *r + strlen (curve));
|
|
||||||
r->key = pSUBKEYCURVE;
|
|
||||||
strcpy (r->u.value, curve);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* Create only a single key. */
|
|
||||||
{
|
|
||||||
/* For ECC we need to ask for the curve before storing the
|
|
||||||
algo because ask_curve may change the algo. */
|
|
||||||
if (algo == PUBKEY_ALGO_ECDSA
|
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
|
||||||
{
|
|
||||||
curve = ask_curve (&algo, NULL);
|
|
||||||
r = xmalloc_clear (sizeof *r + strlen (curve));
|
|
||||||
r->key = pKEYCURVE;
|
|
||||||
strcpy (r->u.value, curve);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
r->key = pKEYTYPE;
|
r->key = pKEYTYPE;
|
||||||
sprintf( r->u.value, "%d", algo );
|
sprintf( r->u.value, "%d", algo);
|
||||||
r->next = para;
|
r->next = para;
|
||||||
para = r;
|
para = r;
|
||||||
|
|
||||||
@ -4286,26 +4199,144 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||||||
r->next = para;
|
r->next = para;
|
||||||
para = r;
|
para = r;
|
||||||
}
|
}
|
||||||
nbits = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (algo == PUBKEY_ALGO_ECDSA
|
r = xmalloc_clear( sizeof *r + 40 );
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
r->key = pKEYGRIP;
|
||||||
|| algo == PUBKEY_ALGO_ECDH)
|
strcpy (r->u.value, key_from_hexgrip);
|
||||||
{
|
r->next = para;
|
||||||
/* The curve has already been set. */
|
para = r;
|
||||||
|
|
||||||
|
xfree (key_from_hexgrip);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nbits = ask_keysize (both? subkey_algo : algo, nbits);
|
char *curve = NULL;
|
||||||
r = xmalloc_clear( sizeof *r + 20 );
|
|
||||||
r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
|
|
||||||
sprintf( r->u.value, "%u", nbits);
|
|
||||||
r->next = para;
|
|
||||||
para = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfree (curve);
|
if (subkey_algo)
|
||||||
|
{
|
||||||
|
/* Create primary and subkey at once. */
|
||||||
|
both = 1;
|
||||||
|
if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
curve = ask_curve (&algo, &subkey_algo);
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pKEYTYPE;
|
||||||
|
sprintf( r->u.value, "%d", algo);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
nbits = 0;
|
||||||
|
r = xmalloc_clear (sizeof *r + strlen (curve));
|
||||||
|
r->key = pKEYCURVE;
|
||||||
|
strcpy (r->u.value, curve);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pKEYTYPE;
|
||||||
|
sprintf( r->u.value, "%d", algo);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
nbits = ask_keysize (algo, 0);
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pKEYLENGTH;
|
||||||
|
sprintf( r->u.value, "%u", nbits);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pKEYUSAGE;
|
||||||
|
strcpy( r->u.value, "sign" );
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pSUBKEYTYPE;
|
||||||
|
sprintf( r->u.value, "%d", subkey_algo);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pSUBKEYUSAGE;
|
||||||
|
strcpy( r->u.value, "encrypt" );
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
if (algo == PUBKEY_ALGO_EDDSA
|
||||||
|
&& subkey_algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
/* Need to switch to a different curve for the
|
||||||
|
encryption key. */
|
||||||
|
xfree (curve);
|
||||||
|
curve = xstrdup ("Curve25519");
|
||||||
|
}
|
||||||
|
r = xmalloc_clear (sizeof *r + strlen (curve));
|
||||||
|
r->key = pSUBKEYCURVE;
|
||||||
|
strcpy (r->u.value, curve);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* Create only a single key. */
|
||||||
|
{
|
||||||
|
/* For ECC we need to ask for the curve before storing the
|
||||||
|
algo because ask_curve may change the algo. */
|
||||||
|
if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
curve = ask_curve (&algo, NULL);
|
||||||
|
r = xmalloc_clear (sizeof *r + strlen (curve));
|
||||||
|
r->key = pKEYCURVE;
|
||||||
|
strcpy (r->u.value, curve);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = pKEYTYPE;
|
||||||
|
sprintf( r->u.value, "%d", algo );
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
|
||||||
|
if (use)
|
||||||
|
{
|
||||||
|
r = xmalloc_clear( sizeof *r + 25 );
|
||||||
|
r->key = pKEYUSAGE;
|
||||||
|
sprintf( r->u.value, "%s%s%s",
|
||||||
|
(use & PUBKEY_USAGE_SIG)? "sign ":"",
|
||||||
|
(use & PUBKEY_USAGE_ENC)? "encrypt ":"",
|
||||||
|
(use & PUBKEY_USAGE_AUTH)? "auth":"" );
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
nbits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|
|| algo == PUBKEY_ALGO_ECDH)
|
||||||
|
{
|
||||||
|
/* The curve has already been set. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nbits = ask_keysize (both? subkey_algo : algo, nbits);
|
||||||
|
r = xmalloc_clear( sizeof *r + 20 );
|
||||||
|
r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
|
||||||
|
sprintf( r->u.value, "%u", nbits);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (curve);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* Default key generation. */
|
else /* Default key generation. */
|
||||||
{
|
{
|
||||||
@ -4547,6 +4578,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||||||
int did_sub = 0;
|
int did_sub = 0;
|
||||||
u32 timestamp;
|
u32 timestamp;
|
||||||
char *cache_nonce = NULL;
|
char *cache_nonce = NULL;
|
||||||
|
int algo;
|
||||||
|
u32 expire;
|
||||||
|
const char *key_from_hexgrip = NULL;
|
||||||
|
|
||||||
if (outctrl->dryrun)
|
if (outctrl->dryrun)
|
||||||
{
|
{
|
||||||
@ -4612,20 +4646,26 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
|
|||||||
node of the subkey but that is more work than just to pass the
|
node of the subkey but that is more work than just to pass the
|
||||||
current timestamp. */
|
current timestamp. */
|
||||||
|
|
||||||
if (!card)
|
algo = get_parameter_algo( para, pKEYTYPE, NULL );
|
||||||
err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
|
expire = get_parameter_u32( para, pKEYEXPIRE );
|
||||||
|
key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
|
||||||
|
if (key_from_hexgrip)
|
||||||
|
err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
|
||||||
|
pub_root, timestamp, expire, 0);
|
||||||
|
else if (!card)
|
||||||
|
err = do_create (algo,
|
||||||
get_parameter_uint( para, pKEYLENGTH ),
|
get_parameter_uint( para, pKEYLENGTH ),
|
||||||
get_parameter_value (para, pKEYCURVE),
|
get_parameter_value (para, pKEYCURVE),
|
||||||
pub_root,
|
pub_root,
|
||||||
timestamp,
|
timestamp,
|
||||||
get_parameter_u32( para, pKEYEXPIRE ), 0,
|
expire, 0,
|
||||||
outctrl->keygen_flags,
|
outctrl->keygen_flags,
|
||||||
get_parameter_passphrase (para),
|
get_parameter_passphrase (para),
|
||||||
&cache_nonce, NULL);
|
&cache_nonce, NULL);
|
||||||
else
|
else
|
||||||
err = gen_card_key (1, get_parameter_algo( para, pKEYTYPE, NULL ),
|
err = gen_card_key (1, algo,
|
||||||
1, pub_root, ×tamp,
|
1, pub_root, ×tamp,
|
||||||
get_parameter_u32 (para, pKEYEXPIRE));
|
expire);
|
||||||
|
|
||||||
/* Get the pointer to the generated public key packet. */
|
/* Get the pointer to the generated public key packet. */
|
||||||
if (!err)
|
if (!err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user