Commit 60109f0b authored by David Woodhouse's avatar David Woodhouse

Shift TSS context out of generic vpninfo

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 46b6bb88
......@@ -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>
......@@ -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;
......@@ -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
}
}
......
......@@ -24,8 +24,9 @@
#include "openconnect-internal.h"
int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
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);
......
......@@ -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,
......@@ -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,
......@@ -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));
......@@ -75,7 +85,7 @@ 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,
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;
......@@ -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,
......@@ -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"),
......@@ -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) {
......@@ -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;
......@@ -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"),
......@@ -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);
......@@ -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 */
......@@ -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
......@@ -349,6 +345,7 @@ struct esp {
};
struct oc_pcsc_ctx;
struct oc_tpm1_ctx;
struct openconnect_info {
const struct vpn_proto *proto;
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment