1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-10 23:49:50 +02:00

gpg: Pass ECDH parameters to OpenPGP smartcards

* g10/call-agent.c (agent_keytocard): Add arg ecdh_param_str.
* g10/keyid.c (ecdh_param_str_from_pk): New.
* g10/card-util.c (card_store_subkey): Pass ECDH params to writekey.
* g10/keygen.c (card_store_key_with_backup): Ditto.
--

Backported from 2.4 - here the gpg part.

See-commit: c03ba92576
This is related to
GnuPG-bug-id: 6378
This commit is contained in:
Werner Koch 2023-10-27 13:56:02 +02:00
parent d03d0add12
commit 92af3f88a9
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
6 changed files with 68 additions and 11 deletions

View File

@ -957,7 +957,8 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
*/ */
int int
agent_keytocard (const char *hexgrip, int keyno, int force, agent_keytocard (const char *hexgrip, int keyno, int force,
const char *serialno, const char *timestamp) const char *serialno, const char *timestamp,
const char *ecdh_param_str)
{ {
int rc; int rc;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
@ -965,8 +966,9 @@ agent_keytocard (const char *hexgrip, int keyno, int force,
memset (&parm, 0, sizeof parm); memset (&parm, 0, sizeof parm);
snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s", snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s%s%s",
force?"--force ": "", hexgrip, serialno, keyno, timestamp); force?"--force ": "", hexgrip, serialno, keyno, timestamp,
ecdh_param_str? " ":"", ecdh_param_str? ecdh_param_str:"");
rc = start_agent (NULL, 1); rc = start_agent (NULL, 1);
if (rc) if (rc)

View File

@ -104,7 +104,8 @@ int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
/* Send the KEYTOCARD command. */ /* Send the KEYTOCARD command. */
int agent_keytocard (const char *hexgrip, int keyno, int force, int agent_keytocard (const char *hexgrip, int keyno, int force,
const char *serialno, const char *timestamp); const char *serialno, const char *timestamp,
const char *ecdh_param_str);
/* Send a SETATTR command to the SCdaemon. */ /* Send a SETATTR command to the SCdaemon. */
gpg_error_t agent_scd_setattr (const char *name, gpg_error_t agent_scd_setattr (const char *name,

View File

@ -1749,8 +1749,9 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys)
int keyno; int keyno;
PKT_public_key *pk; PKT_public_key *pk;
gpg_error_t err; gpg_error_t err;
char *hexgrip; char *hexgrip = NULL;
int rc; int rc;
char *ecdh_param_str = NULL;
gnupg_isotime_t timebuf; gnupg_isotime_t timebuf;
log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY
@ -1824,8 +1825,17 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys)
goto leave; goto leave;
epoch2isotime (timebuf, (time_t)pk->timestamp); epoch2isotime (timebuf, (time_t)pk->timestamp);
rc = agent_keytocard (hexgrip, keyno, rc, info.serialno, timebuf); if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
ecdh_param_str = ecdh_param_str_from_pk (pk);
if (!ecdh_param_str)
{
err = gpg_error_from_syserror ();
goto leave;
}
}
rc = agent_keytocard (hexgrip, keyno, rc, info.serialno,
timebuf, ecdh_param_str);
if (rc) if (rc)
log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc)); log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc));
else else
@ -1834,9 +1844,10 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys)
if (processed_keys) if (processed_keys)
add_to_strlist (processed_keys, hexgrip); add_to_strlist (processed_keys, hexgrip);
} }
xfree (hexgrip);
leave: leave:
xfree (hexgrip);
xfree (ecdh_param_str);
agent_release_card_info (&info); agent_release_card_info (&info);
return okay; return okay;
} }

View File

@ -552,6 +552,7 @@ char *format_hexfingerprint (const char *fingerprint,
char *buffer, size_t buflen); char *buffer, size_t buflen);
gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array); gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip); gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
char *ecdh_param_str_from_pk (PKT_public_key *pk);
/*-- kbnode.c --*/ /*-- kbnode.c --*/

View File

@ -5128,22 +5128,41 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk,
char *cache_nonce = NULL; char *cache_nonce = NULL;
void *kek = NULL; void *kek = NULL;
size_t keklen; size_t keklen;
char *ecdh_param_str = NULL;
sk = copy_public_key (NULL, sub_psk); sk = copy_public_key (NULL, sub_psk);
if (!sk) if (!sk)
return gpg_error_from_syserror (); return gpg_error_from_syserror ();
epoch2isotime (timestamp, (time_t)sk->timestamp); epoch2isotime (timestamp, (time_t)sk->timestamp);
if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
{
ecdh_param_str = ecdh_param_str_from_pk (sk);
if (!ecdh_param_str)
{
free_public_key (sk);
return gpg_error_from_syserror ();
}
}
err = hexkeygrip_from_pk (sk, &hexgrip); err = hexkeygrip_from_pk (sk, &hexgrip);
if (err) if (err)
return err; {
xfree (ecdh_param_str);
free_public_key (sk);
return err;
}
memset(&info, 0, sizeof (info)); memset(&info, 0, sizeof (info));
rc = agent_scd_getattr ("SERIALNO", &info); rc = agent_scd_getattr ("SERIALNO", &info);
if (rc) if (rc)
return (gpg_error_t)rc; {
xfree (ecdh_param_str);
free_public_key (sk);
return (gpg_error_t)rc;
}
rc = agent_keytocard (hexgrip, 2, 1, info.serialno, timestamp); rc = agent_keytocard (hexgrip, 2, 1, info.serialno,
timestamp, ecdh_param_str);
xfree (info.serialno); xfree (info.serialno);
if (rc) if (rc)
{ {
@ -5186,6 +5205,7 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk,
agent_scd_learn (NULL, 1); agent_scd_learn (NULL, 1);
leave: leave:
xfree (ecdh_param_str);
xfree (cache_nonce); xfree (cache_nonce);
gcry_cipher_close (cipherhd); gcry_cipher_close (cipherhd);
xfree (kek); xfree (kek);

View File

@ -994,3 +994,25 @@ hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
} }
return err; return err;
} }
/* Return a hexfied malloced string of the ECDH parameters for an ECDH
* key from the public key PK. Returns NULL on error. */
char *
ecdh_param_str_from_pk (PKT_public_key *pk)
{
const unsigned char *s;
unsigned int n;
if (!pk
|| pk->pubkey_algo != PUBKEY_ALGO_ECDH
|| !gcry_mpi_get_flag (pk->pkey[2], GCRYMPI_FLAG_OPAQUE)
|| !(s = gcry_mpi_get_opaque (pk->pkey[2], &n)) || !n)
{
gpg_err_set_errno (EINVAL);
return NULL; /* Invalid parameter */
}
n = (n+7)/8;
return bin2hex (s, n, NULL);
}