#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,
_("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,
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));
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;
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,
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"),
/* 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) {
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;
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"),
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);
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 */