Skip to content

Commit

Permalink
Shift TSS context out of generic vpninfo
Browse files Browse the repository at this point in the history
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
  • Loading branch information
dwmw2 committed Oct 3, 2018
1 parent 46b6bb8 commit 60109f0
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 69 deletions.
28 changes: 2 additions & 26 deletions gnutls.c
Expand Up @@ -33,11 +33,6 @@
#include <gnutls/pkcs12.h>
#include <gnutls/abstract.h>

#ifdef HAVE_TROUSERS
#include <trousers/tss.h>
#include <trousers/trousers.h>
#endif

#ifdef HAVE_P11KIT
#include <p11-kit/p11-kit.h>
#include <p11-kit/pkcs11.h>
Expand Down Expand Up @@ -1316,7 +1311,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
_("This version of OpenConnect was built without TPM support\n"));
return -EINVAL;
#else
ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig);
ret = load_tpm1_key(vpninfo, &fdata, &pkey, &pkey_sig);
if (ret)
goto out;

Expand Down Expand Up @@ -2319,26 +2314,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL;
#ifdef HAVE_TROUSERS
if (vpninfo->tpm_key_policy) {
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
vpninfo->tpm_key = 0;
}
if (vpninfo->tpm_key) {
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
vpninfo->tpm_key = 0;
}
if (vpninfo->srk_policy) {
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
vpninfo->srk_policy = 0;
}
if (vpninfo->srk) {
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
vpninfo->srk = 0;
}
if (vpninfo->tpm_context) {
Tspi_Context_Close(vpninfo->tpm_context);
vpninfo->tpm_context = 0;
}
release_tpm1_ctx(vpninfo);
#endif
}
}
Expand Down
5 changes: 3 additions & 2 deletions gnutls.h
Expand Up @@ -24,8 +24,9 @@

#include "openconnect-internal.h"

int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig);
void release_tpm1_ctx(struct openconnect_info *info);

char *get_gnutls_cipher(gnutls_session_t session);

Expand Down
105 changes: 73 additions & 32 deletions gnutls_tpm.c
Expand Up @@ -31,6 +31,16 @@
#include "gnutls.h"

#ifdef HAVE_TROUSERS
#include <trousers/tss.h>
#include <trousers/trousers.h>

struct oc_tpm1_ctx {
TSS_HCONTEXT tpm_context;
TSS_HKEY srk;
TSS_HPOLICY srk_policy;
TSS_HKEY tpm_key;
TSS_HPOLICY tpm_key_policy;
};

/* Signing function for TPM privkeys, set with gnutls_privkey_import_ext() */
static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
Expand All @@ -44,7 +54,7 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
_("TPM sign function called for %d bytes.\n"),
data->size);

err = Tspi_Context_CreateObject(vpninfo->tpm_context, TSS_OBJECT_TYPE_HASH,
err = Tspi_Context_CreateObject(vpninfo->tpm1->tpm_context, TSS_OBJECT_TYPE_HASH,
TSS_HASH_OTHER, &hash);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
Expand All @@ -57,13 +67,13 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
vpn_progress(vpninfo, PRG_ERR,
_("Failed to set value in TPM hash object: %s\n"),
Trspi_Error_String(err));
Tspi_Context_CloseObject(vpninfo->tpm_context, hash);
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, hash);
return GNUTLS_E_PK_SIGN_FAILED;
}
err = Tspi_Hash_Sign(hash, vpninfo->tpm_key, &sig->size, &sig->data);
Tspi_Context_CloseObject(vpninfo->tpm_context, hash);
err = Tspi_Hash_Sign(hash, vpninfo->tpm1->tpm_key, &sig->size, &sig->data);
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, hash);
if (err) {
if (vpninfo->tpm_key_policy || err != TPM_E_AUTHFAIL)
if (vpninfo->tpm1->tpm_key_policy || err != TPM_E_AUTHFAIL)
vpn_progress(vpninfo, PRG_ERR,
_("TPM hash signature failed: %s\n"),
Trspi_Error_String(err));
Expand All @@ -75,8 +85,8 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
return 0;
}

int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
{
static const TSS_UUID SRK_UUID = TSS_UUID_SRK;
gnutls_datum_t asn1;
Expand All @@ -91,6 +101,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_strerror(err));
return -EINVAL;
}
vpninfo->tpm1 = calloc(1, sizeof(*vpninfo->tpm1));
/* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */
if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */) {
vpn_progress(vpninfo, PRG_ERR,
Expand Down Expand Up @@ -122,29 +133,29 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
goto out_blob;
}

err = Tspi_Context_Create(&vpninfo->tpm_context);
err = Tspi_Context_Create(&vpninfo->tpm1->tpm_context);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to create TPM context: %s\n"),
Trspi_Error_String(err));
goto out_blob;
}
err = Tspi_Context_Connect(vpninfo->tpm_context, NULL);
err = Tspi_Context_Connect(vpninfo->tpm1->tpm_context, NULL);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to connect TPM context: %s\n"),
Trspi_Error_String(err));
goto out_context;
}
err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm_context, TSS_PS_TYPE_SYSTEM,
SRK_UUID, &vpninfo->srk);
err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm1->tpm_context, TSS_PS_TYPE_SYSTEM,
SRK_UUID, &vpninfo->tpm1->srk);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to load TPM SRK key: %s\n"),
Trspi_Error_String(err));
goto out_context;
}
err = Tspi_GetPolicyObject(vpninfo->srk, TSS_POLICY_USAGE, &vpninfo->srk_policy);
err = Tspi_GetPolicyObject(vpninfo->tpm1->srk, TSS_POLICY_USAGE, &vpninfo->tpm1->srk_policy);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to load TPM SRK policy object: %s\n"),
Expand All @@ -159,11 +170,11 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,

/* We don't seem to get the error here... */
if (pass)
err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
TSS_SECRET_MODE_PLAIN,
strlen(pass), (BYTE *)pass);
else /* Well-known NULL key */
err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
TSS_SECRET_MODE_SHA1,
sizeof(nullpass), (BYTE *)nullpass);
if (err) {
Expand All @@ -176,9 +187,9 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
free(pass);

/* ... we get it here instead. */
err = Tspi_Context_LoadKeyByBlob(vpninfo->tpm_context, vpninfo->srk,
err = Tspi_Context_LoadKeyByBlob(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk,
tss_len, asn1.data + ofs,
&vpninfo->tpm_key);
&vpninfo->tpm1->tpm_key);
if (!err)
break;

Expand All @@ -205,19 +216,19 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
retry_sign:
err = gnutls_privkey_sign_data(*pkey, GNUTLS_DIG_SHA1, 0, fdata, pkey_sig);
if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
if (!vpninfo->tpm_key_policy) {
err = Tspi_Context_CreateObject(vpninfo->tpm_context,
if (!vpninfo->tpm1->tpm_key_policy) {
err = Tspi_Context_CreateObject(vpninfo->tpm1->tpm_context,
TSS_OBJECT_TYPE_POLICY,
TSS_POLICY_USAGE,
&vpninfo->tpm_key_policy);
&vpninfo->tpm1->tpm_key_policy);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to create key policy object: %s\n"),
Trspi_Error_String(err));
goto out_key;
}
err = Tspi_Policy_AssignToObject(vpninfo->tpm_key_policy,
vpninfo->tpm_key);
err = Tspi_Policy_AssignToObject(vpninfo->tpm1->tpm_key_policy,
vpninfo->tpm1->tpm_key);
if (err) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to assign policy to key: %s\n"),
Expand All @@ -230,7 +241,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
if (err)
goto out_key_policy;

err = Tspi_Policy_SetSecret(vpninfo->tpm_key_policy,
err = Tspi_Policy_SetSecret(vpninfo->tpm1->tpm_key_policy,
TSS_SECRET_MODE_PLAIN,
strlen(pass), (void *)pass);
free(pass);
Expand All @@ -247,23 +258,53 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
free(asn1.data);
return 0;
out_key_policy:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
vpninfo->tpm_key_policy = 0;
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key_policy);
vpninfo->tpm1->tpm_key_policy = 0;
out_key:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
vpninfo->tpm_key = 0;
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key);
vpninfo->tpm1->tpm_key = 0;
out_srkpol:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
vpninfo->srk_policy = 0;
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk_policy);
vpninfo->tpm1->srk_policy = 0;
out_srk:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
vpninfo->srk = 0;
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk);
vpninfo->tpm1->srk = 0;
out_context:
Tspi_Context_Close(vpninfo->tpm_context);
vpninfo->tpm_context = 0;
Tspi_Context_Close(vpninfo->tpm1->tpm_context);
vpninfo->tpm1->tpm_context = 0;
out_blob:
free(asn1.data);
free(vpninfo->tpm1);
vpninfo->tpm1 = NULL;
return -EIO;
}

void release_tpm1_ctx(struct openconnect_info *vpninfo)
{
if (!vpninfo->tpm1)
return;

if (vpninfo->tpm1->tpm_key_policy) {
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key_policy);
vpninfo->tpm1->tpm_key = 0;
}
if (vpninfo->tpm1->tpm_key) {
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key);
vpninfo->tpm1->tpm_key = 0;
}
if (vpninfo->tpm1->srk_policy) {
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk_policy);
vpninfo->tpm1->srk_policy = 0;
}
if (vpninfo->tpm1->srk) {
Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk);
vpninfo->tpm1->srk = 0;
}
if (vpninfo->tpm1->tpm_context) {
Tspi_Context_Close(vpninfo->tpm1->tpm_context);
vpninfo->tpm1->tpm_context = 0;
}
free(vpninfo->tpm1);
vpninfo->tpm1 = NULL;
};
#endif /* HAVE_TROUSERS */
11 changes: 2 additions & 9 deletions openconnect-internal.h
Expand Up @@ -57,10 +57,6 @@
#include <gnutls/abstract.h>
#include <gnutls/x509.h>
#include <gnutls/crypto.h>
#ifdef HAVE_TROUSERS
#include <trousers/tss.h>
#include <trousers/trousers.h>
#endif
#endif

#ifdef HAVE_ICONV
Expand Down Expand Up @@ -349,6 +345,7 @@ struct esp {
};

struct oc_pcsc_ctx;
struct oc_tpm1_ctx;

struct openconnect_info {
const struct vpn_proto *proto;
Expand Down Expand Up @@ -504,11 +501,7 @@ struct openconnect_info {
char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */
char gnutls_prio[256];
#ifdef HAVE_TROUSERS
TSS_HCONTEXT tpm_context;
TSS_HKEY srk;
TSS_HPOLICY srk_policy;
TSS_HKEY tpm_key;
TSS_HPOLICY tpm_key_policy;
struct oc_tpm1_ctx *tpm1;
#endif
#endif /* OPENCONNECT_GNUTLS */
struct pin_cache *pin_cache;
Expand Down

0 comments on commit 60109f0

Please sign in to comment.