mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
agent: Add new shadow key type and functions to call tpm2daemon
* agent/call-tpm2d.c: New. * divert-tpm2.c: New. * agent/Makefile.am: Add new files. * agent/agent.h (DAEMON_TPM2D): New. Add stub fucntions. * agent/call-daemon.c (GNUPG_MODULE_NAME_TPM2DAEMON): New. * agent/command.c (do_one_keyinfo): Handle tpmv2. * agent/gpg-agent.c (oTpm2daemonProgram): New. (opts): New option --tpm2daemon-program. (parse_rereadable_options): Handle option. * agent/pkdecrypt.c (agent_pkdecrypt): Divert to tpm2d. (agent_pksign_do): Ditto. --- A new shadow key type: "tpm2-v1" is introduced signalling that the shadowed key is handled by the tpm2daemon. A function to identify this type is introduced and diversions to the tpm2daemon functions are conditioned on this function for pkign and pkdecrypt where the same diversions to scd are currently done. The (info) field of the shadowed key stores the actual TPM key. The TPM key is encrypted so only the physical TPM it was created on can read it (so no special protection is required for the info filed), but if the (info) field becomes corrupt or damaged, the key will be lost (unlike the token case, where the key is actually moved inside the token). Note, this commit adds handling for existing TPM format shadow keys, but there is still no way to create them. Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Additional changes: * Add ChangeLog entries. * Some minor indentation fixes. * agent/Makefile.am (gpg_agent_SOURCES): Change to make distcheck work. * agent/agent.h [!HAVE_LIBTSS]: Do not return -EINVAL but an gpg_error_t. Mark args as unused. * agent/protect.c (agent_is_tpm2_key): Free BUF. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
62a7854816
commit
1f995b9ba4
11 changed files with 519 additions and 22 deletions
145
agent/divert-tpm2.c
Normal file
145
agent/divert-tpm2.c
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue