mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
gpg: Allow to create a Kyber key from keygrips.
* agent/cvt-openpgp.c (extract_private_key): Support Kyber algorithms. * common/openpgp-oid.c (map_gcry_pk_to_openpgp): Map KEM to Kyber. * common/sexputil.c (get_pk_algo_from_key): Increase buffer for use with "kyber1024". * g10/call-agent.c (agent_get_keyinfo): Fix warning. * g10/keygen.c (do_create_from_keygrip): Support Kyber. (ask_algo): Ditto. -- To test create a standard key and the use --edit-key and "addkey" with selection 13 and use the comma delimited keygrips. GnuPG-bug-id: 7014
This commit is contained in:
parent
68d9bc9c35
commit
03d53c88cc
@ -1384,6 +1384,17 @@ extract_private_key (gcry_sexp_t s_key, int req_private_key_data,
|
|||||||
err = gcry_sexp_extract_param (list, NULL, format,
|
err = gcry_sexp_extract_param (list, NULL, format,
|
||||||
array+0, array+1, NULL);
|
array+0, array+1, NULL);
|
||||||
}
|
}
|
||||||
|
else if ( !strcmp (name, (algoname = "kyber512"))
|
||||||
|
|| !strcmp (name, (algoname = "kyber768"))
|
||||||
|
|| !strcmp (name, (algoname = "kyber1024")))
|
||||||
|
{
|
||||||
|
format = "/ps?";
|
||||||
|
elems = "ps?";
|
||||||
|
npkey = 1;
|
||||||
|
nskey = 2;
|
||||||
|
err = gcry_sexp_extract_param (list, NULL, format,
|
||||||
|
array+0, array+1, NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
err = gpg_error (GPG_ERR_PUBKEY_ALGO);
|
||||||
|
@ -377,7 +377,7 @@ divert_pksign (ctrl_t ctrl, const unsigned char *grip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Decrypt the value given asn an S-expression in CIPHER using the
|
/* Decrypt the value given as an s-expression in CIPHER using the
|
||||||
key identified by SHADOW_INFO and return the plaintext in an
|
key identified by SHADOW_INFO and return the plaintext in an
|
||||||
allocated buffer in R_BUF. The padding information is stored at
|
allocated buffer in R_BUF. The padding information is stored at
|
||||||
R_PADDING with -1 for not known. */
|
R_PADDING with -1 for not known. */
|
||||||
|
@ -623,6 +623,7 @@ map_gcry_pk_to_openpgp (enum gcry_pk_algos algo)
|
|||||||
case GCRY_PK_EDDSA: return PUBKEY_ALGO_EDDSA;
|
case GCRY_PK_EDDSA: return PUBKEY_ALGO_EDDSA;
|
||||||
case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA;
|
case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA;
|
||||||
case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH;
|
case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH;
|
||||||
|
case GCRY_PK_KEM: return PUBKEY_ALGO_KYBER;
|
||||||
default: return algo < 110 ? (pubkey_algo_t)algo : 0;
|
default: return algo < 110 ? (pubkey_algo_t)algo : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -992,7 +992,7 @@ get_pk_algo_from_key (gcry_sexp_t key)
|
|||||||
gcry_sexp_t list;
|
gcry_sexp_t list;
|
||||||
const char *s;
|
const char *s;
|
||||||
size_t n;
|
size_t n;
|
||||||
char algoname[6];
|
char algoname[10];
|
||||||
int algo = 0;
|
int algo = 0;
|
||||||
|
|
||||||
list = gcry_sexp_nth (key, 1);
|
list = gcry_sexp_nth (key, 1);
|
||||||
|
@ -2469,7 +2469,7 @@ agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
|
|||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
char line[ASSUAN_LINELENGTH];
|
char line[ASSUAN_LINELENGTH];
|
||||||
struct keyinfo_data_parm_s keyinfo;
|
struct keyinfo_data_parm_s keyinfo;
|
||||||
char *s;
|
const char *s;
|
||||||
|
|
||||||
memset (&keyinfo, 0,sizeof keyinfo);
|
memset (&keyinfo, 0,sizeof keyinfo);
|
||||||
|
|
||||||
|
92
g10/keygen.c
92
g10/keygen.c
@ -1,7 +1,7 @@
|
|||||||
/* keygen.c - Generate a key pair
|
/* keygen.c - Generate a key pair
|
||||||
* Copyright (C) 1998-2007, 2009-2011 Free Software Foundation, Inc.
|
* Copyright (C) 1998-2007, 2009-2011 Free Software Foundation, Inc.
|
||||||
* Copyright (C) 2014, 2015, 2016, 2017, 2018 Werner Koch
|
* Copyright (C) 2014, 2015, 2016, 2017, 2018 Werner Koch
|
||||||
* Copyright (C) 2020 g10 Code GmbH
|
* Copyright (C) 2020, 2024 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -1501,10 +1501,24 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
gcry_sexp_t s_key;
|
gcry_sexp_t s_key;
|
||||||
|
gcry_sexp_t s_key2 = NULL;
|
||||||
const char *algoelem;
|
const char *algoelem;
|
||||||
|
char *hexkeygrip_buffer = NULL;
|
||||||
|
char *hexkeygrip2 = NULL;
|
||||||
|
|
||||||
if (hexkeygrip[0] == '&')
|
if (hexkeygrip[0] == '&')
|
||||||
hexkeygrip++;
|
hexkeygrip++;
|
||||||
|
if (strchr (hexkeygrip, ','))
|
||||||
|
{
|
||||||
|
hexkeygrip_buffer = xtrystrdup (hexkeygrip);
|
||||||
|
if (!hexkeygrip_buffer)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
hexkeygrip = hexkeygrip_buffer;
|
||||||
|
hexkeygrip2 = strchr (hexkeygrip_buffer, ',');
|
||||||
|
if (hexkeygrip2)
|
||||||
|
*hexkeygrip2++ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (algo)
|
switch (algo)
|
||||||
{
|
{
|
||||||
@ -1514,16 +1528,21 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
case PUBKEY_ALGO_ECDH:
|
case PUBKEY_ALGO_ECDH:
|
||||||
case PUBKEY_ALGO_ECDSA: algoelem = ""; break;
|
case PUBKEY_ALGO_ECDSA: algoelem = ""; break;
|
||||||
case PUBKEY_ALGO_EDDSA: algoelem = ""; break;
|
case PUBKEY_ALGO_EDDSA: algoelem = ""; break;
|
||||||
default: return gpg_error (GPG_ERR_INTERNAL);
|
case PUBKEY_ALGO_KYBER: algoelem = ""; break;
|
||||||
|
default:
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return gpg_error (GPG_ERR_INTERNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Ask the agent for the public key matching HEXKEYGRIP. */
|
/* Ask the agent for the public key matching HEXKEYGRIP. */
|
||||||
if (cardkey)
|
if (cardkey)
|
||||||
{
|
{
|
||||||
err = agent_scd_readkey (ctrl, hexkeygrip, &s_key, NULL);
|
err = agent_scd_readkey (ctrl, hexkeygrip, &s_key, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1531,16 +1550,41 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
|
|
||||||
err = agent_readkey (ctrl, 0, hexkeygrip, &public);
|
err = agent_readkey (ctrl, 0, hexkeygrip, &public);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
err = gcry_sexp_sscan (&s_key, NULL, public,
|
err = gcry_sexp_sscan (&s_key, NULL, public,
|
||||||
gcry_sexp_canon_len (public, 0, NULL, NULL));
|
gcry_sexp_canon_len (public, 0, NULL, NULL));
|
||||||
xfree (public);
|
xfree (public);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
{
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (hexkeygrip2)
|
||||||
|
{
|
||||||
|
err = agent_readkey (ctrl, 0, hexkeygrip2, &public);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (s_key);
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = gcry_sexp_sscan (&s_key2, NULL, public,
|
||||||
|
gcry_sexp_canon_len (public, 0, NULL, NULL));
|
||||||
|
xfree (public);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
gcry_sexp_release (s_key);
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For X448 we force the use of v5 packets. */
|
/* For X448 and Kyber we force the use of v5 packets. */
|
||||||
if (curve_is_448 (s_key))
|
if (curve_is_448 (s_key) || algo == PUBKEY_ALGO_KYBER)
|
||||||
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
*keygen_flags |= KEYGEN_FLAG_CREATE_V5_KEY;
|
||||||
|
|
||||||
/* Build a public key packet. */
|
/* Build a public key packet. */
|
||||||
@ -1549,6 +1593,8 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
gcry_sexp_release (s_key);
|
gcry_sexp_release (s_key);
|
||||||
|
gcry_sexp_release (s_key2);
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,7 +1604,9 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
pk->expiredate = pk->timestamp + expireval;
|
pk->expiredate = pk->timestamp + expireval;
|
||||||
pk->pubkey_algo = algo;
|
pk->pubkey_algo = algo;
|
||||||
|
|
||||||
if (algo == PUBKEY_ALGO_ECDSA
|
if (algo == PUBKEY_ALGO_KYBER)
|
||||||
|
err = ecckey_from_sexp (pk->pkey, s_key, s_key2, algo);
|
||||||
|
else if (algo == PUBKEY_ALGO_ECDSA
|
||||||
|| algo == PUBKEY_ALGO_EDDSA
|
|| algo == PUBKEY_ALGO_EDDSA
|
||||||
|| algo == PUBKEY_ALGO_ECDH )
|
|| algo == PUBKEY_ALGO_ECDH )
|
||||||
err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
|
err = ecckey_from_sexp (pk->pkey, s_key, NULL, algo);
|
||||||
@ -1568,16 +1616,20 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
{
|
{
|
||||||
log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
|
log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
|
||||||
gcry_sexp_release (s_key);
|
gcry_sexp_release (s_key);
|
||||||
|
gcry_sexp_release (s_key2);
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
gcry_sexp_release (s_key);
|
gcry_sexp_release (s_key);
|
||||||
|
gcry_sexp_release (s_key2);
|
||||||
|
|
||||||
pkt = xtrycalloc (1, sizeof *pkt);
|
pkt = xtrycalloc (1, sizeof *pkt);
|
||||||
if (!pkt)
|
if (!pkt)
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
free_public_key (pk);
|
free_public_key (pk);
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,6 +1637,7 @@ do_create_from_keygrip (ctrl_t ctrl, int algo,
|
|||||||
pkt->pkt.public_key = pk;
|
pkt->pkt.public_key = pk;
|
||||||
add_kbnode (pub_root, new_kbnode (pkt));
|
add_kbnode (pub_root, new_kbnode (pkt));
|
||||||
|
|
||||||
|
xfree (hexkeygrip_buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2479,7 +2532,26 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen (answer) != 40 &&
|
if (strlen (answer) == 40+1+40 && answer[40]==',')
|
||||||
|
{
|
||||||
|
int algo1, algo2;
|
||||||
|
|
||||||
|
answer[40] = 0;
|
||||||
|
algo1 = check_keygrip (ctrl, answer);
|
||||||
|
algo2 = check_keygrip (ctrl, answer+41);
|
||||||
|
answer[40] = ',';
|
||||||
|
if (algo1 == PUBKEY_ALGO_ECDH && algo2 == PUBKEY_ALGO_KYBER)
|
||||||
|
{
|
||||||
|
algo = PUBKEY_ALGO_KYBER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!algo1 || !algo2)
|
||||||
|
tty_printf (_("No key with this keygrip\n"));
|
||||||
|
else
|
||||||
|
tty_printf ("Invalid combination for dual algo (%d,%d)\n",
|
||||||
|
algo1, algo2);
|
||||||
|
}
|
||||||
|
else if (strlen (answer) != 40 &&
|
||||||
!(answer[0] == '&' && strlen (answer+1) == 40))
|
!(answer[0] == '&' && strlen (answer+1) == 40))
|
||||||
tty_printf
|
tty_printf
|
||||||
(_("Not a valid keygrip (expecting 40 hex digits)\n"));
|
(_("Not a valid keygrip (expecting 40 hex digits)\n"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user