aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/agent.h10
-rw-r--r--agent/command.c20
-rw-r--r--agent/findkey.c5
-rw-r--r--agent/protect.c72
4 files changed, 90 insertions, 17 deletions
diff --git a/agent/agent.h b/agent/agent.h
index de0d25fb3..e2d2df4ee 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -451,7 +451,8 @@ int agent_pk_get_algo (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,
- unsigned char **r_shadow_info);
+ unsigned char **r_shadow_info,
+ unsigned char **r_shadow_info_type);
gpg_error_t agent_delete_key (ctrl_t ctrl, const char *desc_text,
const unsigned char *grip,
int force, int only_stubs);
@@ -535,8 +536,15 @@ unsigned char *make_shadow_info (const char *serialno, const char *idstring);
int agent_shadow_key (const unsigned char *pubkey,
const unsigned char *shadow_info,
unsigned char **result);
+int agent_shadow_key_type (const unsigned char *pubkey,
+ const unsigned char *shadow_info,
+ const unsigned char *type,
+ unsigned char **result);
gpg_error_t agent_get_shadow_info (const unsigned char *shadowkey,
unsigned char const **shadow_info);
+gpg_error_t agent_get_shadow_info_type (const unsigned char *shadowkey,
+ unsigned char const **shadow_info,
+ unsigned char **shadow_type);
gpg_error_t parse_shadow_info (const unsigned char *shadow_info,
char **r_hexsn, char **r_idstr, int *r_pinlen);
gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo,
diff --git a/agent/command.c b/agent/command.c
index d374fd06f..0430745e4 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -1198,6 +1198,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
char *fpr = NULL;
int keytype;
unsigned char *shadow_info = NULL;
+ unsigned char *shadow_info_type = NULL;
char *serialno = NULL;
char *idstr = NULL;
const char *keytypestr;
@@ -1208,7 +1209,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
char ttlbuf[20];
char flagsbuf[5];
- err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info);
+ err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info,
+ &shadow_info_type);
if (err)
{
if (in_ssh && gpg_err_code (err) == GPG_ERR_NOT_FOUND)
@@ -1280,9 +1282,18 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
if (shadow_info)
{
- err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
- if (err)
- goto leave;
+ if (strcmp (shadow_info_type, "t1-v1") == 0)
+ {
+ err = parse_shadow_info (shadow_info, &serialno, &idstr, NULL);
+ if (err)
+ goto leave;
+ }
+ else
+ {
+ log_error ("unrecognised shadow key type %s\n", shadow_info_type);
+ err = GPG_ERR_BAD_KEY;
+ goto leave;
+ }
}
if (!data)
@@ -1317,6 +1328,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
leave:
xfree (fpr);
+ xfree (shadow_info_type);
xfree (shadow_info);
xfree (serialno);
xfree (idstr);
diff --git a/agent/findkey.c b/agent/findkey.c
index 1494615c4..0951a754e 100644
--- a/agent/findkey.c
+++ b/agent/findkey.c
@@ -1320,7 +1320,8 @@ agent_key_available (const unsigned char *grip)
S-expression. */
gpg_error_t
agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
- int *r_keytype, unsigned char **r_shadow_info)
+ int *r_keytype, unsigned char **r_shadow_info,
+ unsigned char **r_shadow_info_type)
{
gpg_error_t err;
unsigned char *buf;
@@ -1367,7 +1368,7 @@ agent_key_info_from_file (ctrl_t ctrl, const unsigned char *grip,
const unsigned char *s;
size_t n;
- err = agent_get_shadow_info (buf, &s);
+ err = agent_get_shadow_info_type (buf, &s, r_shadow_info_type);
if (!err)
{
n = gcry_sexp_canon_len (s, 0, NULL, NULL);
diff --git a/agent/protect.c b/agent/protect.c
index e3bbf3ed5..54666e717 100644
--- a/agent/protect.c
+++ b/agent/protect.c
@@ -1516,9 +1516,10 @@ make_shadow_info (const char *serialno, const char *idstring)
to. The input parameters are expected to be valid canonicalized
S-expressions */
int
-agent_shadow_key (const unsigned char *pubkey,
- const unsigned char *shadow_info,
- unsigned char **result)
+agent_shadow_key_type (const unsigned char *pubkey,
+ const unsigned char *shadow_info,
+ const unsigned char *type,
+ unsigned char **result)
{
const unsigned char *s;
const unsigned char *point;
@@ -1574,7 +1575,7 @@ agent_shadow_key (const unsigned char *pubkey,
log_assert (depth == 1);
/* Calculate required length by taking in account: the "shadowed-"
- prefix, the "shadowed", "t1-v1" as well as some parenthesis */
+ prefix, the "shadowed", shadow type as well as some parenthesis */
n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1;
*result = xtrymalloc (n);
p = (char*)*result;
@@ -1584,7 +1585,7 @@ agent_shadow_key (const unsigned char *pubkey,
/* (10:public-key ...)*/
memcpy (p, pubkey+14, point - (pubkey+14));
p += point - (pubkey+14);
- p = stpcpy (p, "(8:shadowed5:t1-v1");
+ p += sprintf (p, "(8:shadowed%d:%s", (int)strlen(type), type);
memcpy (p, shadow_info, shadow_info_len);
p += shadow_info_len;
*p++ = ')';
@@ -1594,11 +1595,20 @@ agent_shadow_key (const unsigned char *pubkey,
return 0;
}
+int
+agent_shadow_key (const unsigned char *pubkey,
+ const unsigned char *shadow_info,
+ unsigned char **result)
+{
+ return agent_shadow_key_type (pubkey, shadow_info, "t1-v1", result);
+}
+
/* Parse a canonical encoded shadowed key and return a pointer to the
- inner list with the shadow_info */
+ inner list with the shadow_info and the shadow type */
gpg_error_t
-agent_get_shadow_info (const unsigned char *shadowkey,
- unsigned char const **shadow_info)
+agent_get_shadow_info_type (const unsigned char *shadowkey,
+ unsigned char const **shadow_info,
+ unsigned char **shadow_type)
{
const unsigned char *s;
size_t n;
@@ -1650,17 +1660,59 @@ agent_get_shadow_info (const unsigned char *shadowkey,
n = snext (&s);
if (!n)
return gpg_error (GPG_ERR_INV_SEXP);
- if (smatch (&s, n, "t1-v1"))
+ if (shadow_type) {
+ char *buf = xtrymalloc(n+1);
+ memcpy(buf, s, n);
+ buf[n] = '\0';
+ *shadow_type = buf;
+ }
+
+ if (smatch (&s, n, "t1-v1") || smatch(&s, n, "tpm2-v1"))
{
if (*s != '(')
return gpg_error (GPG_ERR_INV_SEXP);
- *shadow_info = s;
+ if (shadow_info)
+ *shadow_info = s;
}
else
return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
return 0;
}
+gpg_error_t
+agent_get_shadow_info(const unsigned char *shadowkey,
+ unsigned char const **shadow_info)
+{
+ return agent_get_shadow_info_type(shadowkey, shadow_info, NULL);
+}
+
+int
+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);
+ if (err)
+ return 0;
+
+ err = agent_get_shadow_info_type(buf, NULL, &type);
+ if (err)
+ return 0;
+
+ 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)
+{
+ 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