diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 8 | ||||
-rw-r--r-- | g10/call-agent.h | 3 | ||||
-rw-r--r-- | g10/card-util.c | 19 | ||||
-rw-r--r-- | g10/keydb.h | 1 | ||||
-rw-r--r-- | g10/keygen.c | 12 | ||||
-rw-r--r-- | g10/keyid.c | 22 |
6 files changed, 57 insertions, 8 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index 131f56ae7..b0bccc0a5 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1096,7 +1096,8 @@ agent_keytotpm (ctrl_t ctrl, const char *hexgrip) */ 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) { int rc; char line[ASSUAN_LINELENGTH]; @@ -1104,8 +1105,9 @@ agent_keytocard (const char *hexgrip, int keyno, int force, memset (&parm, 0, sizeof parm); - snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s", - force?"--force ": "", hexgrip, serialno, keyno, timestamp); + snprintf (line, DIM(line), "KEYTOCARD %s%s %s OPENPGP.%d %s%s%s", + force?"--force ": "", hexgrip, serialno, keyno, timestamp, + ecdh_param_str? " ":"", ecdh_param_str? ecdh_param_str:""); rc = start_agent (NULL, 1); if (rc) diff --git a/g10/call-agent.h b/g10/call-agent.h index 80595cacc..45af95422 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -135,7 +135,8 @@ int agent_keytotpm (ctrl_t ctrl, const char *hexgrip); /* Send the KEYTOCARD command. */ 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. */ gpg_error_t agent_scd_setattr (const char *name, diff --git a/g10/card-util.c b/g10/card-util.c index a3297fb71..d680c4d0a 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -1805,8 +1805,9 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys) int keyno; PKT_public_key *pk; gpg_error_t err; - char *hexgrip; + char *hexgrip = NULL; int rc; + char *ecdh_param_str = NULL; gnupg_isotime_t timebuf; log_assert (node->pkt->pkttype == PKT_PUBLIC_KEY @@ -1880,8 +1881,19 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys) goto leave; 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) log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc)); else @@ -1890,9 +1902,10 @@ card_store_subkey (KBNODE node, int use, strlist_t *processed_keys) if (processed_keys) add_to_strlist (processed_keys, hexgrip); } - xfree (hexgrip); leave: + xfree (hexgrip); + xfree (ecdh_param_str); agent_release_card_info (&info); return okay; } diff --git a/g10/keydb.h b/g10/keydb.h index 9323e3137..1a66d664e 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -576,6 +576,7 @@ char *format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen); 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); +char *ecdh_param_str_from_pk (PKT_public_key *pk); /*-- kbnode.c --*/ diff --git a/g10/keygen.c b/g10/keygen.c index c97783124..7f54f7da0 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -5327,12 +5327,20 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, char *cache_nonce = NULL; void *kek = NULL; size_t keklen; + char *ecdh_param_str = NULL; sk = copy_public_key (NULL, sub_psk); if (!sk) return gpg_error_from_syserror (); 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) + return gpg_error_from_syserror (); + } + err = hexkeygrip_from_pk (sk, &hexgrip); if (err) goto leave; @@ -5345,7 +5353,8 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, goto leave; } - rc = agent_keytocard (hexgrip, 2, 1, info.serialno, timestamp); + rc = agent_keytocard (hexgrip, 2, 1, info.serialno, + timestamp, ecdh_param_str); xfree (info.serialno); if (rc) { @@ -5388,6 +5397,7 @@ card_store_key_with_backup (ctrl_t ctrl, PKT_public_key *sub_psk, agent_scd_learn (NULL, 1); leave: + xfree (ecdh_param_str); xfree (cache_nonce); gcry_cipher_close (cipherhd); xfree (kek); diff --git a/g10/keyid.c b/g10/keyid.c index ca6564c5c..9191fec92 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -1141,3 +1141,25 @@ hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip) } 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); +} |