aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <[email protected]>2018-03-05 19:16:40 +0000
committerWerner Koch <[email protected]>2018-03-09 09:06:40 +0000
commitc4c7b7d7ba6b9d52bb7884b4bb4f84b7dd96340b (patch)
treeb858f015aaff86bea9702995a533c7e94a24ab25
parentagent: plumb in TPM handling (diff)
downloadgnupg-c4c7b7d7ba6b9d52bb7884b4bb4f84b7dd96340b.tar.gz
gnupg-c4c7b7d7ba6b9d52bb7884b4bb4f84b7dd96340b.zip
g10: add ability to transfer a private key to the tpm
* g10/keyedit.c (cmdKEYTOTPM): New enum value. (cmds): New command "keytotpm". (keyedit_menu): Implement cmdKEYTOTPM. -- Exactly like the gpg --edit-key command keytosc, keytotpm has been added which immedately converts the private key file to TPM shadowed form. Once this is done, the key cannot be recovered and may only be used via the TPM of the computer system on which the conversion was done. If that system is ever lost, or its TPM cleared, the shadowed key becomes unusable. Signed-off-by: James Bottomley <[email protected]>
-rw-r--r--g10/call-agent.c22
-rw-r--r--g10/call-agent.h3
-rw-r--r--g10/keyedit.c45
3 files changed, 69 insertions, 1 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c
index b1f589bbc..8b224f7f0 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -778,6 +778,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;
+}
+
int
agent_keytocard (const char *hexgrip, int keyno, int force,
diff --git a/g10/call-agent.h b/g10/call-agent.h
index 53775c5c8..ba4c398c0 100644
--- a/g10/call-agent.h
+++ b/g10/call-agent.h
@@ -91,6 +91,9 @@ gpg_error_t agent_scd_apdu (const char *hexapdu, unsigned int *r_sw);
/* 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 2c33a29dd..038c31821 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -1241,7 +1241,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
};
@@ -1292,6 +1292,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 */
@@ -1789,6 +1791,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 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;