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 @@ ...@@ -33,11 +33,6 @@
#include <gnutls/pkcs12.h> #include <gnutls/pkcs12.h>
#include <gnutls/abstract.h> #include <gnutls/abstract.h>
#ifdef HAVE_TROUSERS
#include <trousers/tss.h>
#include <trousers/trousers.h>
#endif
#ifdef HAVE_P11KIT #ifdef HAVE_P11KIT
#include <p11-kit/p11-kit.h> #include <p11-kit/p11-kit.h>
#include <p11-kit/pkcs11.h> #include <p11-kit/pkcs11.h>
...@@ -1316,7 +1311,7 @@ static int load_certificate(struct openconnect_info *vpninfo) ...@@ -1316,7 +1311,7 @@ static int load_certificate(struct openconnect_info *vpninfo)
_("This version of OpenConnect was built without TPM support\n")); _("This version of OpenConnect was built without TPM support\n"));
return -EINVAL; return -EINVAL;
#else #else
ret = load_tpm_key(vpninfo, &fdata, &pkey, &pkey_sig); ret = load_tpm1_key(vpninfo, &fdata, &pkey, &pkey_sig);
if (ret) if (ret)
goto out; goto out;
...@@ -2319,26 +2314,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final) ...@@ -2319,26 +2314,7 @@ void openconnect_close_https(struct openconnect_info *vpninfo, int final)
gnutls_certificate_free_credentials(vpninfo->https_cred); gnutls_certificate_free_credentials(vpninfo->https_cred);
vpninfo->https_cred = NULL; vpninfo->https_cred = NULL;
#ifdef HAVE_TROUSERS #ifdef HAVE_TROUSERS
if (vpninfo->tpm_key_policy) { release_tpm1_ctx(vpninfo);
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;
}
#endif #endif
} }
} }
......
...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
#include "openconnect-internal.h" #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); 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); char *get_gnutls_cipher(gnutls_session_t session);
......
...@@ -31,6 +31,16 @@ ...@@ -31,6 +31,16 @@
#include "gnutls.h" #include "gnutls.h"
#ifdef HAVE_TROUSERS #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() */ /* Signing function for TPM privkeys, set with gnutls_privkey_import_ext() */
static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo, 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, ...@@ -44,7 +54,7 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
_("TPM sign function called for %d bytes.\n"), _("TPM sign function called for %d bytes.\n"),
data->size); 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); TSS_HASH_OTHER, &hash);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
...@@ -57,13 +67,13 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo, ...@@ -57,13 +67,13 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to set value in TPM hash object: %s\n"), _("Failed to set value in TPM hash object: %s\n"),
Trspi_Error_String(err)); 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; return GNUTLS_E_PK_SIGN_FAILED;
} }
err = Tspi_Hash_Sign(hash, vpninfo->tpm_key, &sig->size, &sig->data); err = Tspi_Hash_Sign(hash, vpninfo->tpm1->tpm_key, &sig->size, &sig->data);
Tspi_Context_CloseObject(vpninfo->tpm_context, hash); Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, hash);
if (err) { 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, vpn_progress(vpninfo, PRG_ERR,
_("TPM hash signature failed: %s\n"), _("TPM hash signature failed: %s\n"),
Trspi_Error_String(err)); Trspi_Error_String(err));
...@@ -75,8 +85,8 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo, ...@@ -75,8 +85,8 @@ static int tpm_sign_fn(gnutls_privkey_t key, void *_vpninfo,
return 0; 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) gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
{ {
static const TSS_UUID SRK_UUID = TSS_UUID_SRK; static const TSS_UUID SRK_UUID = TSS_UUID_SRK;
gnutls_datum_t asn1; gnutls_datum_t asn1;
...@@ -91,6 +101,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -91,6 +101,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_strerror(err)); gnutls_strerror(err));
return -EINVAL; return -EINVAL;
} }
vpninfo->tpm1 = calloc(1, sizeof(*vpninfo->tpm1));
/* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */ /* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */
if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */) { if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
...@@ -122,29 +133,29 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -122,29 +133,29 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
goto out_blob; goto out_blob;
} }
err = Tspi_Context_Create(&vpninfo->tpm_context); err = Tspi_Context_Create(&vpninfo->tpm1->tpm_context);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to create TPM context: %s\n"), _("Failed to create TPM context: %s\n"),
Trspi_Error_String(err)); Trspi_Error_String(err));
goto out_blob; goto out_blob;
} }
err = Tspi_Context_Connect(vpninfo->tpm_context, NULL); err = Tspi_Context_Connect(vpninfo->tpm1->tpm_context, NULL);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to connect TPM context: %s\n"), _("Failed to connect TPM context: %s\n"),
Trspi_Error_String(err)); Trspi_Error_String(err));
goto out_context; goto out_context;
} }
err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm_context, TSS_PS_TYPE_SYSTEM, err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm1->tpm_context, TSS_PS_TYPE_SYSTEM,
SRK_UUID, &vpninfo->srk); SRK_UUID, &vpninfo->tpm1->srk);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to load TPM SRK key: %s\n"), _("Failed to load TPM SRK key: %s\n"),
Trspi_Error_String(err)); Trspi_Error_String(err));
goto out_context; 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) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to load TPM SRK policy object: %s\n"), _("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, ...@@ -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... */ /* We don't seem to get the error here... */
if (pass) if (pass)
err = Tspi_Policy_SetSecret(vpninfo->srk_policy, err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
TSS_SECRET_MODE_PLAIN, TSS_SECRET_MODE_PLAIN,
strlen(pass), (BYTE *)pass); strlen(pass), (BYTE *)pass);
else /* Well-known NULL key */ else /* Well-known NULL key */
err = Tspi_Policy_SetSecret(vpninfo->srk_policy, err = Tspi_Policy_SetSecret(vpninfo->tpm1->srk_policy,
TSS_SECRET_MODE_SHA1, TSS_SECRET_MODE_SHA1,
sizeof(nullpass), (BYTE *)nullpass); sizeof(nullpass), (BYTE *)nullpass);
if (err) { if (err) {
...@@ -176,9 +187,9 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -176,9 +187,9 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
free(pass); free(pass);
/* ... we get it here instead. */ /* ... 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, tss_len, asn1.data + ofs,
&vpninfo->tpm_key); &vpninfo->tpm1->tpm_key);
if (!err) if (!err)
break; break;
...@@ -205,19 +216,19 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -205,19 +216,19 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
retry_sign: retry_sign:
err = gnutls_privkey_sign_data(*pkey, GNUTLS_DIG_SHA1, 0, fdata, pkey_sig); err = gnutls_privkey_sign_data(*pkey, GNUTLS_DIG_SHA1, 0, fdata, pkey_sig);
if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) { if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
if (!vpninfo->tpm_key_policy) { if (!vpninfo->tpm1->tpm_key_policy) {
err = Tspi_Context_CreateObject(vpninfo->tpm_context, err = Tspi_Context_CreateObject(vpninfo->tpm1->tpm_context,
TSS_OBJECT_TYPE_POLICY, TSS_OBJECT_TYPE_POLICY,
TSS_POLICY_USAGE, TSS_POLICY_USAGE,
&vpninfo->tpm_key_policy); &vpninfo->tpm1->tpm_key_policy);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to create key policy object: %s\n"), _("Failed to create key policy object: %s\n"),
Trspi_Error_String(err)); Trspi_Error_String(err));
goto out_key; goto out_key;
} }
err = Tspi_Policy_AssignToObject(vpninfo->tpm_key_policy, err = Tspi_Policy_AssignToObject(vpninfo->tpm1->tpm_key_policy,
vpninfo->tpm_key); vpninfo->tpm1->tpm_key);
if (err) { if (err) {
vpn_progress(vpninfo, PRG_ERR, vpn_progress(vpninfo, PRG_ERR,
_("Failed to assign policy to key: %s\n"), _("Failed to assign policy to key: %s\n"),
...@@ -230,7 +241,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -230,7 +241,7 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
if (err) if (err)
goto out_key_policy; 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, TSS_SECRET_MODE_PLAIN,
strlen(pass), (void *)pass); strlen(pass), (void *)pass);
free(pass); free(pass);
...@@ -247,23 +258,53 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, ...@@ -247,23 +258,53 @@ int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
free(asn1.data); free(asn1.data);
return 0; return 0;
out_key_policy: out_key_policy:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy); Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key_policy);
vpninfo->tpm_key_policy = 0; vpninfo->tpm1->tpm_key_policy = 0;
out_key: out_key:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key); Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->tpm_key);
vpninfo->tpm_key = 0; vpninfo->tpm1->tpm_key = 0;
out_srkpol: out_srkpol:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy); Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk_policy);
vpninfo->srk_policy = 0; vpninfo->tpm1->srk_policy = 0;
out_srk: out_srk:
Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk); Tspi_Context_CloseObject(vpninfo->tpm1->tpm_context, vpninfo->tpm1->srk);
vpninfo->srk = 0; vpninfo->tpm1->srk = 0;
out_context: out_context:
Tspi_Context_Close(vpninfo->tpm_context); Tspi_Context_Close(vpninfo->tpm1->tpm_context);
vpninfo->tpm_context = 0; vpninfo->tpm1->tpm_context = 0;
out_blob: out_blob:
free(asn1.data); free(asn1.data);
free(vpninfo->tpm1);
vpninfo->tpm1 = NULL;
return -EIO; 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 */ #endif /* HAVE_TROUSERS */
...@@ -57,10 +57,6 @@ ...@@ -57,10 +57,6 @@
#include <gnutls/abstract.h> #include <gnutls/abstract.h>
#include <gnutls/x509.h> #include <gnutls/x509.h>
#include <gnutls/crypto.h> #include <gnutls/crypto.h>
#ifdef HAVE_TROUSERS
#include <trousers/tss.h>
#include <trousers/trousers.h>
#endif
#endif #endif
#ifdef HAVE_ICONV #ifdef HAVE_ICONV
...@@ -349,6 +345,7 @@ struct esp { ...@@ -349,6 +345,7 @@ struct esp {
}; };
struct oc_pcsc_ctx; struct oc_pcsc_ctx;
struct oc_tpm1_ctx;
struct openconnect_info { struct openconnect_info {
const struct vpn_proto *proto; const struct vpn_proto *proto;
...@@ -504,11 +501,7 @@ struct openconnect_info { ...@@ -504,11 +501,7 @@ struct openconnect_info {
char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */ char local_cert_md5[MD5_SIZE * 2 + 1]; /* For CSD */
char gnutls_prio[256]; char gnutls_prio[256];
#ifdef HAVE_TROUSERS #ifdef HAVE_TROUSERS
TSS_HCONTEXT tpm_context; struct oc_tpm1_ctx *tpm1;
TSS_HKEY srk;
TSS_HPOLICY srk_policy;
TSS_HKEY tpm_key;
TSS_HPOLICY tpm_key_policy;
#endif #endif
#endif /* OPENCONNECT_GNUTLS */ #endif /* OPENCONNECT_GNUTLS */
struct pin_cache *pin_cache; 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