summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/Makefile.am7
-rw-r--r--agent/agent.h58
-rw-r--r--agent/call-daemon.c3
-rw-r--r--agent/call-tpm2d.c248
-rw-r--r--agent/command.c5
-rw-r--r--agent/divert-tpm2.c145
-rw-r--r--agent/gpg-agent.c12
-rw-r--r--agent/keyformat.txt12
-rw-r--r--agent/pkdecrypt.c8
-rw-r--r--agent/pksign.c16
-rw-r--r--agent/protect.c27
11 files changed, 519 insertions, 22 deletions
diff --git a/agent/Makefile.am b/agent/Makefile.am
index 2688ba967..ee7c38d9d 100644
--- a/agent/Makefile.am
+++ b/agent/Makefile.am
@@ -38,6 +38,12 @@ endif
AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS)
+if HAVE_LIBTSS
+tpm2_sources = divert-tpm2.c call-tpm2d.c
+else
+tpm2_sources =
+endif
+
gpg_agent_SOURCES = \
gpg-agent.c agent.h \
command.c command-ssh.c \
@@ -55,6 +61,7 @@ gpg_agent_SOURCES = \
cvt-openpgp.c cvt-openpgp.h \
call-scd.c \
call-daemon.c \
+ $(tpm2_sources) \
learncard.c
common_libs = $(libcommon)
diff --git a/agent/agent.h b/agent/agent.h
index 4d29ce9c9..94dd8b8f8 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -59,6 +59,7 @@
enum daemon_type
{
DAEMON_SCD,
+ DAEMON_TPM2D,
DAEMON_MAX_TYPE
};
@@ -459,6 +460,7 @@ gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
const unsigned char *grip,
gcry_sexp_t *result);
int agent_pk_get_algo (gcry_sexp_t s_key);
+int agent_is_tpm2_key(gcry_sexp_t s_key);
int agent_key_available (const unsigned char *grip);
gpg_error_t agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
int *r_keytype,
@@ -577,6 +579,52 @@ gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name,
const char *fpr, int flag);
void agent_reload_trustlist (void);
+/*-- divert-tpm2.c --*/
+#ifdef HAVE_LIBTSS
+int divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *digest, size_t digestlen, int algo,
+ const unsigned char *shadow_info, unsigned char **r_sig,
+ size_t *r_siglen);
+int divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *cipher,
+ const unsigned char *shadow_info,
+ char **r_buf, size_t *r_len, int *r_padding);
+int divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip,
+ gcry_sexp_t s_skey);
+#else /*!HAVE_LIBTSS*/
+static inline int
+divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *digest,
+ size_t digestlen, int algo,
+ const unsigned char *shadow_info,
+ unsigned char **r_sig,
+ size_t *r_siglen)
+{
+ (void)ctrl; (void)desc_text; (void)digest; (void)digestlen;
+ (void)algo; (void)shadow_info; (void)r_sig; (void)r_siglen;
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+}
+static inline int
+divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *cipher,
+ const unsigned char *shadow_info,
+ char **r_buf, size_t *r_len,
+ int *r_padding)
+{
+ (void)ctrl; (void)desc_text; (void)cipher; (void)shadow_info;
+ (void)r_buf; (void)r_len; (void)r_padding;
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+}
+static inline int
+divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip,
+ gcry_sexp_t s_skey)
+{
+ (void)ctrl; (void)grip; (void)s_key;
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+}
+#endif /*!HAVE_LIBTSS*/
+
+
/*-- divert-scd.c --*/
int divert_pksign (ctrl_t ctrl, const char *desc_text,
@@ -606,6 +654,16 @@ void agent_daemon_check_aliveness (void);
void agent_reset_daemon (ctrl_t ctrl);
void agent_kill_daemon (enum daemon_type type);
+/*-- call-tpm2d.c --*/
+int agent_tpm2d_writekey (ctrl_t ctrl, unsigned char **shadow_info,
+ gcry_sexp_t s_skey);
+int agent_tpm2d_pksign (ctrl_t ctrl, const unsigned char *digest,
+ size_t digestlen, const unsigned char *shadow_info,
+ unsigned char **r_sig, size_t *r_siglen);
+int agent_tpm2d_pkdecrypt (ctrl_t ctrl, const unsigned char *cipher,
+ size_t cipherlen, const unsigned char *shadow_info,
+ char **r_buf, size_t *r_len);
+
/*-- call-scd.c --*/
int agent_card_learn (ctrl_t ctrl,
void (*kpinfo_cb)(void*, const char *),
diff --git a/agent/call-daemon.c b/agent/call-daemon.c
index 5147f1557..144400875 100644
--- a/agent/call-daemon.c
+++ b/agent/call-daemon.c
@@ -45,7 +45,8 @@
* same order as given by the daemon_type enum. */
static const int daemon_modules[DAEMON_MAX_TYPE] =
{
- GNUPG_MODULE_NAME_SCDAEMON
+ GNUPG_MODULE_NAME_SCDAEMON,
+ GNUPG_MODULE_NAME_TPM2DAEMON
};
/* Definition of module local data of the CTRL structure. */
diff --git a/agent/call-tpm2d.c b/agent/call-tpm2d.c
new file mode 100644
index 000000000..6fae5d85a
--- /dev/null
+++ b/agent/call-tpm2d.c
@@ -0,0 +1,248 @@
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include "agent.h"
+#include <assuan.h>
+#include "../common/strlist.h"
+#include "../common/sexp-parse.h"
+#include "../common/i18n.h"
+
+static int
+start_tpm2d (ctrl_t ctrl)
+{
+ return daemon_start (DAEMON_TPM2D, ctrl);
+}
+
+static int
+unlock_tpm2d (ctrl_t ctrl, gpg_error_t err)
+{
+ return daemon_unlock (DAEMON_TPM2D, ctrl, err);
+}
+
+static assuan_context_t
+daemon_ctx (ctrl_t ctrl)
+{
+ return daemon_type_ctx (DAEMON_TPM2D, ctrl);
+}
+
+struct inq_parm_s {
+ assuan_context_t ctx;
+ gpg_error_t (*getpin_cb)(ctrl_t, const char *, char **);
+ ctrl_t ctrl;
+ /* The next fields are used by inq_keydata. */
+ const unsigned char *keydata;
+ size_t keydatalen;
+ /* following only used by inq_extra */
+ const unsigned char *extra;
+ size_t extralen;
+ char *pin;
+};
+
+static gpg_error_t
+inq_needpin (void *opaque, const char *line)
+{
+ struct inq_parm_s *parm = opaque;
+ char *pin = NULL;
+ gpg_error_t rc;
+ const char *s;
+
+ if ((s = has_leading_keyword (line, "NEEDPIN")))
+ {
+ rc = parm->getpin_cb (parm->ctrl, s, &pin);
+ if (!rc)
+ rc = assuan_send_data (parm->ctx, pin, strlen(pin));
+ parm->pin = pin;
+ }
+ else
+ {
+ log_error ("unsupported inquiry '%s'\n", line);
+ rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
+ }
+
+ return rc;
+}
+
+static gpg_error_t
+inq_keydata (void *opaque, const char *line)
+{
+ struct inq_parm_s *parm = opaque;
+
+ if (has_leading_keyword (line, "KEYDATA"))
+ return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
+ else
+ return inq_needpin (opaque, line);
+}
+
+static gpg_error_t
+inq_extra (void *opaque, const char *line)
+{
+ struct inq_parm_s *parm = opaque;
+
+ if (has_leading_keyword (line, "EXTRA"))
+ return assuan_send_data (parm->ctx, parm->extra, parm->extralen);
+ else
+ return inq_keydata (opaque, line);
+}
+
+int
+agent_tpm2d_writekey (ctrl_t ctrl, unsigned char **shadow_info,
+ gcry_sexp_t s_skey)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ size_t n;
+ unsigned char *kbuf;
+ membuf_t data;
+ struct inq_parm_s inqparm;
+ size_t len;
+
+ rc = start_tpm2d (ctrl);
+ if (rc)
+ return rc;
+
+ /* note: returned data is TPM protected so no need for a sensitive context */
+ init_membuf(&data, 4096);
+
+ inqparm.ctx = daemon_ctx (ctrl);
+ inqparm.getpin_cb = agent_ask_new_passphrase;
+ inqparm.ctrl = ctrl;
+ inqparm.pin = NULL;
+
+ n = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0);
+ kbuf = xtrymalloc (n);
+ gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, kbuf, n);
+ inqparm.keydata = kbuf;
+ inqparm.keydatalen = n;
+ snprintf(line, sizeof(line), "IMPORT");
+
+ rc = assuan_transact (daemon_ctx (ctrl), line,
+ put_membuf_cb, &data,
+ inq_keydata, &inqparm,
+ NULL, NULL);
+ xfree (kbuf);
+ xfree (inqparm.pin);
+ if (rc)
+ {
+ xfree (get_membuf (&data, &len));
+ return unlock_tpm2d (ctrl, rc);
+ }
+
+ *shadow_info = get_membuf (&data, &len);
+
+ return unlock_tpm2d (ctrl, 0);
+}
+
+static gpg_error_t
+pin_cb (ctrl_t ctrl, const char *prompt, char **passphrase)
+{
+ *passphrase = agent_get_cache (ctrl, ctrl->keygrip, CACHE_MODE_USER);
+ if (*passphrase)
+ return 0;
+ return agent_get_passphrase(ctrl, passphrase,
+ _("Please enter your passphrase, so that the "
+ "secret key can be unlocked for this session"),
+ prompt, NULL, 0,
+ ctrl->keygrip, CACHE_MODE_USER, NULL);
+}
+
+int
+agent_tpm2d_pksign (ctrl_t ctrl, const unsigned char *digest,
+ size_t digestlen, const unsigned char *shadow_info,
+ unsigned char **r_sig, size_t *r_siglen)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ membuf_t data;
+ struct inq_parm_s inqparm;
+
+ rc = start_tpm2d (ctrl);
+ if (rc)
+ return rc;
+
+ init_membuf (&data, 1024);
+
+ inqparm.ctx = daemon_ctx (ctrl);
+ inqparm.getpin_cb = pin_cb;
+ inqparm.ctrl = ctrl;
+ inqparm.keydata = shadow_info;
+ inqparm.keydatalen = gcry_sexp_canon_len (shadow_info, 0, NULL, NULL);
+ inqparm.extra = digest;
+ inqparm.extralen = digestlen;
+ inqparm.pin = NULL;
+
+ snprintf(line, sizeof(line), "PKSIGN");
+
+ rc = assuan_transact (daemon_ctx (ctrl), line,
+ put_membuf_cb, &data,
+ inq_extra, &inqparm,
+ NULL, NULL);
+ if (!rc)
+ agent_put_cache (ctrl, ctrl->keygrip, CACHE_MODE_USER, inqparm.pin, 0);
+
+ xfree (inqparm.pin);
+
+ if (rc)
+ {
+ size_t len;
+ xfree (get_membuf (&data, &len));
+ return unlock_tpm2d (ctrl, rc);
+ }
+
+ *r_sig = get_membuf (&data, r_siglen);
+
+ return unlock_tpm2d (ctrl, 0);
+}
+
+int
+agent_tpm2d_pkdecrypt (ctrl_t ctrl, const unsigned char *cipher,
+ size_t cipherlen, const unsigned char *shadow_info,
+ char **r_buf, size_t *r_len)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ membuf_t data;
+ struct inq_parm_s inqparm;
+
+ rc = start_tpm2d (ctrl);
+ if (rc)
+ return rc;
+
+ init_membuf (&data, 1024);
+
+ inqparm.ctx = daemon_ctx (ctrl);
+ inqparm.getpin_cb = pin_cb;
+ inqparm.ctrl = ctrl;
+ inqparm.keydata = shadow_info;
+ inqparm.keydatalen = gcry_sexp_canon_len (shadow_info, 0, NULL, NULL);
+ inqparm.extra = cipher;
+ inqparm.extralen = cipherlen;
+ inqparm.pin = NULL;
+
+ snprintf(line, sizeof(line), "PKDECRYPT");
+
+ rc = assuan_transact (daemon_ctx (ctrl), line,
+ put_membuf_cb, &data,
+ inq_extra, &inqparm,
+ NULL, NULL);
+ if (!rc)
+ agent_put_cache (ctrl, ctrl->keygrip, CACHE_MODE_USER, inqparm.pin, 0);
+
+ xfree (inqparm.pin);
+
+ if (rc)
+ {
+ size_t len;
+ xfree (get_membuf (&data, &len));
+ return unlock_tpm2d (ctrl, rc);
+ }
+
+ *r_buf = get_membuf (&data, r_len);
+
+ return unlock_tpm2d (ctrl, 0);
+}
diff --git a/agent/command.c b/agent/command.c
index 8384560cd..87446a233 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1314,6 +1314,11 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
if (err)
goto leave;
}
+ else if (strcmp (shadow_info_type, "tpm2-v1") == 0)
+ {
+ serialno = xstrdup("TPM-Protected");
+ idstr = NULL;
+ }
else
{
log_error ("unrecognised shadow key type %s\n", shadow_info_type);
diff --git a/agent/divert-tpm2.c b/agent/divert-tpm2.c
new file mode 100644
index 000000000..4946f7a8a
--- /dev/null
+++ b/agent/divert-tpm2.c
@@ -0,0 +1,145 @@
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include "agent.h"
+#include "../common/i18n.h"
+#include "../common/sexp-parse.h"
+
+int
+divert_tpm2_pksign (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *digest, size_t digestlen, int algo,
+ const unsigned char *shadow_info, unsigned char **r_sig,
+ size_t *r_siglen)
+{
+ return agent_tpm2d_pksign(ctrl, digest, digestlen,
+ shadow_info, r_sig, r_siglen);
+}
+
+
+static gpg_error_t
+agent_write_tpm2_shadow_key (ctrl_t ctrl, const unsigned char *grip,
+ unsigned char *shadow_info)
+{
+ gpg_error_t err;
+ unsigned char *shdkey;
+ unsigned char *pkbuf;
+ size_t len;
+ gcry_sexp_t s_pkey;
+
+ err = agent_public_key_from_file (ctrl, grip, &s_pkey);
+ len = gcry_sexp_sprint(s_pkey, GCRYSEXP_FMT_CANON, NULL, 0);
+ pkbuf = xtrymalloc (len);
+ gcry_sexp_sprint (s_pkey, GCRYSEXP_FMT_CANON, pkbuf, len);
+ gcry_sexp_release (s_pkey);
+
+ err = agent_shadow_key_type (pkbuf, shadow_info, "tpm2-v1", &shdkey);
+ xfree (pkbuf);
+ if (err)
+ {
+ log_error ("shadowing the key failed: %s\n", gpg_strerror (err));
+ return err;
+ }
+
+ len = gcry_sexp_canon_len (shdkey, 0, NULL, NULL);
+ err = agent_write_private_key (grip, shdkey, len, 1 /*force*/,
+ NULL, NULL, 0);
+ xfree (shdkey);
+ if (err)
+ log_error ("error writing key: %s\n", gpg_strerror (err));
+
+ return err;
+}
+
+int
+divert_tpm2_writekey (ctrl_t ctrl, const unsigned char *grip,
+ gcry_sexp_t s_skey)
+{
+ int ret;
+ /* shadow_info is always shielded so no special handling required */
+ unsigned char *shadow_info;
+
+ ret = agent_tpm2d_writekey(ctrl, &shadow_info, s_skey);
+ if (!ret) {
+ ret = agent_write_tpm2_shadow_key (ctrl, grip, shadow_info);
+ xfree (shadow_info);
+ }
+ return ret;
+}
+
+int
+divert_tpm2_pkdecrypt (ctrl_t ctrl, const char *desc_text,
+ const unsigned char *cipher,
+ const unsigned char *shadow_info,
+ char **r_buf, size_t *r_len, int *r_padding)
+{
+ const unsigned char *s;
+ size_t n;
+
+ *r_padding = -1;
+
+ (void)desc_text;
+
+ s = cipher;
+ if (*s != '(')
+ return gpg_error (GPG_ERR_INV_SEXP);
+ s++;
+ n = snext (&s);
+ if (!n)
+ return gpg_error (GPG_ERR_INV_SEXP);
+ if (!smatch (&s, n, "enc-val"))
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ if (*s != '(')
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ s++;
+ n = snext (&s);
+ if (!n)
+ return gpg_error (GPG_ERR_INV_SEXP);
+ if (smatch (&s, n, "rsa"))
+ {
+ *r_padding = 0;
+ if (*s != '(')
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ s++;
+ n = snext (&s);
+ if (!n)
+ return gpg_error (GPG_ERR_INV_SEXP);
+ if (!smatch (&s, n, "a"))
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ n = snext (&s);
+ }
+ else if (smatch (&s, n, "ecdh"))
+ {
+ if (*s != '(')
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ s++;
+ n = snext (&s);
+ if (!n)
+ return gpg_error (GPG_ERR_INV_SEXP);
+ if (smatch (&s, n, "s"))
+ {
+ n = snext (&s);
+ s += n;
+ if (*s++ != ')')
+ return gpg_error (GPG_ERR_INV_SEXP);
+ if (*s++ != '(')
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ n = snext (&s);
+ if (!n)
+ return gpg_error (GPG_ERR_INV_SEXP);
+ }
+ if (!smatch (&s, n, "e"))
+ return gpg_error (GPG_ERR_UNKNOWN_SEXP);
+ n = snext (&s);
+ }
+ else
+ return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+
+ return agent_tpm2d_pkdecrypt (ctrl, s, n, shadow_info, r_buf, r_len);
+}
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index b3a0c230c..74c2108b1 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -102,6 +102,7 @@ enum cmd_and_opt_values
oLCmessages,
oXauthority,
oScdaemonProgram,
+ oTpm2daemonProgram,
oDefCacheTTL,
oDefCacheTTLSSH,
oMaxCacheTTL,
@@ -199,6 +200,8 @@ static gpgrt_opt_t opts[] = {
/* */ N_("do not use the SCdaemon") ),
ARGPARSE_s_s (oScdaemonProgram, "scdaemon-program",
/* */ N_("|PGM|use PGM as the SCdaemon program") ),
+ ARGPARSE_s_s (oTpm2daemonProgram, "tpm2daemon-program",
+ /* */ N_("|PGM|use PGM as the tpm2daemon program") ),
ARGPARSE_s_n (oDisableCheckOwnSocket, "disable-check-own-socket", "@"),
ARGPARSE_s_s (oExtraSocket, "extra-socket",
@@ -905,7 +908,14 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread)
opt.pinentry_invisible_char = xtrystrdup (pargs->r.ret_str); break;
break;
case oPinentryTimeout: opt.pinentry_timeout = pargs->r.ret_ulong; break;
- case oScdaemonProgram: opt.daemon_program[DAEMON_SCD] = pargs->r.ret_str; break;
+
+ case oTpm2daemonProgram:
+ opt.daemon_program[DAEMON_TPM2D] = pargs->r.ret_str;
+ break;
+
+ case oScdaemonProgram:
+ opt.daemon_program[DAEMON_SCD] = pargs->r.ret_str;
+ break;
case oDisableScdaemon: opt.disable_daemon[DAEMON_SCD] = 1; break;
case oDisableCheckOwnSocket: disable_check_own_socket = 1; break;
diff --git a/agent/keyformat.txt b/agent/keyformat.txt
index 88c3a2d36..3467f3bc5 100644
--- a/agent/keyformat.txt
+++ b/agent/keyformat.txt
@@ -312,8 +312,9 @@ to keys stored on a token:
(comment whatever)
)
-The currently used protocol is "t1-v1" (token info version 1). The
-second list with the information has this layout:
+The currently used protocols are "t1-v1" (token info version 1) and
+"tpm2-v1" (TPM format key information). The second list with the
+information has this layout for "t1-v1":
(card_serial_number id_string_of_key fixed_pin_length)
@@ -322,6 +323,13 @@ the PIN; a value of 0 indicates that this information is not
available. The rationale for this field is that some pinpad equipped
readers don't allow passing a variable length PIN.
+This is the (info) layout for "tpm2-v1":
+
+(parent tpm_private_string tpm_public_string)
+
+Although this precise format is encapsulated inside the tpm2daemon
+itself and nothing in gpg ever uses this.
+
More items may be added to the list.
** OpenPGP Private Key Transfer Format
diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c
index da370bb0a..16a15b9d0 100644
--- a/agent/pkdecrypt.c
+++ b/agent/pkdecrypt.c
@@ -88,8 +88,12 @@ agent_pkdecrypt (ctrl_t ctrl, const char *desc_text,
goto leave;
}
- err = divert_pkdecrypt (ctrl, desc_text, ctrl->keygrip, ciphertext,
- shadow_info, &buf, &len, r_padding);
+ if (agent_is_tpm2_key (s_skey))
+ err = divert_tpm2_pkdecrypt (ctrl, desc_text, ciphertext, shadow_info,
+ &buf, &len, r_padding);
+ else
+ err = divert_pkdecrypt (ctrl, desc_text, ctrl->keygrip, ciphertext,
+ shadow_info, &buf, &len, r_padding);
if (err)
{
log_error ("smartcard decryption failed: %s\n", gpg_strerror (err));
diff --git a/agent/pksign.c b/agent/pksign.c
index ca9a35292..00b31ee45 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -397,11 +397,17 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
if (desc_text)
agent_modify_description (desc_text, NULL, s_pkey, &desc2);
- err = divert_pksign (ctrl, desc2? desc2 : desc_text,
- ctrl->keygrip,
- data, datalen,
- ctrl->digest.algo,
- shadow_info, &buf, &len);
+ if (agent_is_tpm2_key (s_skey))
+ err = divert_tpm2_pksign (ctrl, desc2? desc2 : desc_text,
+ data, datalen,
+ ctrl->digest.algo,
+ shadow_info, &buf, &len);
+ else
+ err = divert_pksign (ctrl, desc2? desc2 : desc_text,
+ ctrl->keygrip,
+ data, datalen,
+ ctrl->digest.algo,
+ shadow_info, &buf, &len);
xfree (desc2);
}
if (err)
diff --git a/agent/protect.c b/agent/protect.c
index 54666e717..76ead444b 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -1679,41 +1679,46 @@ agent_get_shadow_info_type (const unsigned char *shadowkey,
return 0;
}
+
gpg_error_t
-agent_get_shadow_info(const unsigned char *shadowkey,
- unsigned char const **shadow_info)
+agent_get_shadow_info (const unsigned char *shadowkey,
+ unsigned char const **shadow_info)
{
- return agent_get_shadow_info_type(shadowkey, shadow_info, NULL);
+ return agent_get_shadow_info_type (shadowkey, shadow_info, NULL);
}
+
int
-agent_is_tpm2_key(gcry_sexp_t s_skey)
+agent_is_tpm2_key (gcry_sexp_t s_skey)
{
unsigned char *buf;
unsigned char *type;
size_t len;
gpg_error_t err;
- err = make_canon_sexp(s_skey, &buf, &len);
+ err = make_canon_sexp (s_skey, &buf, &len);
if (err)
return 0;
- err = agent_get_shadow_info_type(buf, NULL, &type);
+ err = agent_get_shadow_info_type (buf, NULL, &type);
if (err)
return 0;
+ xfree (buf);
- err = strcmp(type, "tpm2-v1") == 0;
- xfree(type);
+ err = strcmp (type, "tpm2-v1") == 0;
+ xfree (type);
return err;
}
+
gpg_error_t
-agent_get_shadow_type(const unsigned char *shadowkey,
- unsigned char **shadow_type)
+agent_get_shadow_type (const unsigned char *shadowkey,
+ unsigned char **shadow_type)
{
- return agent_get_shadow_info_type(shadowkey, NULL, shadow_type);
+ return agent_get_shadow_info_type (shadowkey, NULL, shadow_type);
}
+
/* Parse the canonical encoded SHADOW_INFO S-expression. On success
the hex encoded serial number is returned as a malloced strings at
R_HEXSN and the Id string as a malloced string at R_IDSTR. On