aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--agent/command.c52
-rw-r--r--agent/divert-tpm2.c2
-rw-r--r--g10/call-agent.c22
-rw-r--r--g10/call-agent.h3
-rw-r--r--g10/keyedit.c45
5 files changed, 123 insertions, 1 deletions
diff --git a/agent/command.c b/agent/command.c
index 87446a233..095f38ba3 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -3114,6 +3114,57 @@ cmd_put_secret (assuan_context_t ctx, char *line)
+static const char hlp_keytotpm[] =
+ "KEYTOTPM <hexstring_with_keygrip>\n"
+ "\n";
+static gpg_error_t
+cmd_keytotpm (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err = 0;
+ unsigned char grip[20];
+ gcry_sexp_t s_skey;
+ unsigned char *shadow_info = NULL;
+
+ if (ctrl->restricted)
+ return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
+
+ err = parse_keygrip (ctx, line, grip);
+ if (err)
+ goto leave;
+
+ if (agent_key_available (grip))
+ {
+ err =gpg_error (GPG_ERR_NO_SECKEY);
+ goto leave;
+ }
+
+ err = agent_key_from_file (ctrl, NULL, ctrl->server_local->keydesc, grip,
+ &shadow_info, CACHE_MODE_IGNORE, NULL,
+ &s_skey, NULL);
+ if (err)
+ {
+ xfree (shadow_info);
+ goto leave;
+ }
+ if (shadow_info)
+ {
+ /* Key is on a TPM or smartcard already. */
+ xfree (shadow_info);
+ gcry_sexp_release (s_skey);
+ err = gpg_error (GPG_ERR_UNUSABLE_SECKEY);
+ goto leave;
+ }
+
+ err = divert_tpm2_writekey (ctrl, grip, s_skey);
+ gcry_sexp_release (s_skey);
+
+ leave:
+ return leave_cmd (ctx, err);
+}
+
+
+
static const char hlp_getval[] =
"GETVAL <key>\n"
"\n"
@@ -3812,6 +3863,7 @@ register_commands (assuan_context_t ctx)
{ "RELOADAGENT", cmd_reloadagent,hlp_reloadagent },
{ "GETINFO", cmd_getinfo, hlp_getinfo },
{ "KEYTOCARD", cmd_keytocard, hlp_keytocard },
+ { "KEYTOTPM", cmd_keytotpm, hlp_keytotpm },
{ NULL }
};
int i, rc;
diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c
index 4946f7a8a..0741c6847 100644
--- a/agent/divert-tpm2.c
+++ b/agent/divert-tpm2.c
@@ -18,6 +18,8 @@ divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text,
const unsigned char *shadow_info, unsigned char **r_sig,
size_t *r_siglen)
{
+ (void)desc_text;
+ (void)algo;
return agent_tpm2d_pksign(ctrl, digest, digestlen,
shadow_info, r_sig, r_siglen);
}
diff --git a/g10/call-agent.c b/g10/call-agent.c
index a553ef67a..fb80489b2 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -1060,6 +1060,28 @@ agent_scd_apdu (const char *hexapdu, unsigned int *r_sw)
return err;
}
+int
+agent_keytotpm (ctrl_t ctrl, const char *hexgrip)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ struct default_inq_parm_s parm;
+
+ snprintf(line, DIM(line), "KEYTOTPM %s\n", hexgrip);
+
+ rc = start_agent (ctrl, 0);
+ if (rc)
+ return rc;
+ parm.ctx = agent_ctx;
+ parm.ctrl = ctrl;
+
+ rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
+ NULL, NULL);
+ if (rc)
+ log_log (GPGRT_LOGLVL_ERROR, _("error from TPM: %s\n"), gpg_strerror (rc));
+ return rc;
+}
+
/* Used by:
* card_store_subkey
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 4a66af2aa..efea7ec4a 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -126,6 +126,9 @@ gpg_error_t agent_scd_getattr_one (const char *name, char **r_value);
/* Update INFO with the attribute NAME. */
int agent_scd_getattr (const char *name, struct agent_card_info_s *info);
+/* send the KEYTOTPM command */
+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);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 596662dda..c8a127551 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1247,7 +1247,7 @@ enum cmdids
#endif /*!NO_TRUST_MODELS*/
cmdSHOWPREF,
cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
- cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD,
+ cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdKEYTOTPM, cmdBKUPTOCARD,
cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP
};
@@ -1298,6 +1298,8 @@ static struct
N_("add a key to a smartcard")},
{ "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("move a key to a smartcard")},
+ { "keytotpm", cmdKEYTOTPM, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
+ N_("convert a key to TPM form using the local TPM")},
{ "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_NEED_SUBSK,
N_("move a backup key to a smartcard")},
#endif /*ENABLE_CARD_SUPPORT */
@@ -1796,6 +1798,47 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
}
break;
+ case cmdKEYTOTPM:
+ /* FIXME need to store the key and not commit until later */
+ {
+ kbnode_t node = NULL;
+ switch (count_selected_keys (keyblock))
+ {
+ case 0:
+ if (cpr_get_answer_is_yes
+ ("keyedit.keytocard.use_primary",
+ /* TRANSLATORS: Please take care: This is about
+ moving the key and not about removing it. */
+ _("Really move the primary key? (y/N) ")))
+ node = keyblock;
+ break;
+ case 1:
+ for (node = keyblock; node; node = node->next)
+ {
+ if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && node->flag & NODFLG_SELKEY)
+ break;
+ }
+ break;
+ default:
+ tty_printf (_("You must select exactly one key.\n"));
+ break;
+ }
+ if (node)
+ {
+ PKT_public_key *xxpk = node->pkt->pkt.public_key;
+ char *hexgrip;
+
+ hexkeygrip_from_pk (xxpk, &hexgrip);
+ if (!agent_keytotpm (ctrl, hexgrip))
+ {
+ redisplay = 1;
+ }
+ xfree (hexgrip);
+ }
+ }
+ break;
+
case cmdKEYTOCARD:
{
KBNODE node = NULL;