Skip to content

Commit

Permalink
Parse TPM2 ASN.1 blob
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 8, 2018
1 parent 81f1fce commit e1f2bb7
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 9 deletions.
20 changes: 13 additions & 7 deletions configure.ac
Expand Up @@ -484,17 +484,23 @@ case "$ssl_library" in
CFLAGS="$oldcflags"

tss2lib=
AC_MSG_CHECKING([for tss2 library])
AC_CHECK_LIB([tss], [TSS_Create], [tss2lib=tss2],
AC_CHECK_LIB([TSS_Create], [ibmtss], [tss2lib=ibmtss], []))
if test "%tss2lib" != ""; then
AC_CHECK_HEADER($tss2lib/tss.h, AC_DEFINE_UNQUOTED(HAVE_TSS2, $tss2lib, [TSS2 library]), [])
AC_CHECK_LIB([tss], [TSS_Create], [tss2inc=tss2
tss2lib=tss],
AC_CHECK_LIB([TSS_Create], [ibmtss], [tss2inc=ibmtss
tss2lib=ibmtss], []))
if test "$tss2lib" != ""; then
PKG_CHECK_MODULES(TASN1, libtasn1, [], [tss2lib=])
fi
if test "$tss2lib" != ""; then
AC_CHECK_HEADER($tss2inc/tss.h,
[AC_DEFINE_UNQUOTED(HAVE_TSS2, $tss2inc, [TSS2 library])
AC_SUBST(TSS2_LIBS, [-l$tss2lib])], [])
fi

AC_DEFINE(OPENCONNECT_GNUTLS, 1, [Using GnuTLS])
AC_SUBST(SSL_PC, [gnutls])
AC_SUBST(SSL_LIBS, ['$(GNUTLS_LIBS)'])
AC_SUBST(SSL_CFLAGS, ['$(GNUTLS_CFLAGS)'])
AC_SUBST(SSL_LIBS, ['$(GNUTLS_LIBS) $(TASN1_LIBS) $(TSS2_LIBS)'])
AC_SUBST(SSL_CFLAGS, ['$(GNUTLS_CFLAGS) $(TASN1_CFLAGS)'])
;;

*)
Expand Down
90 changes: 88 additions & 2 deletions gnutls_tpm2.c
Expand Up @@ -22,7 +22,7 @@

#include <gnutls/gnutls.h>
#include "openconnect-internal.h"

#include <libtasn1.h>
#include "gnutls.h"

#ifdef HAVE_TSS2
Expand All @@ -31,12 +31,33 @@

struct oc_tpm2_ctx {
};
#include <libtasn1.h>

const asn1_static_node tpmkey_asn1_tab[] = {
{ "TPMKey", 536875024, NULL },
{ NULL, 1073741836, NULL },
{ "TPMKey", 536870917, NULL },
{ "type", 1073741836, NULL },
{ "emptyAuth", 1610637316, NULL },
{ NULL, 2056, "0"},
{ "parent", 1610637315, NULL },
{ NULL, 2056, "1"},
{ "pubkey", 1610637319, NULL },
{ NULL, 2056, "2"},
{ "privkey", 7, NULL },
{ NULL, 0, NULL }
};

int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
{
gnutls_datum_t asn1;
int err;
ASN1_TYPE tpmkey_def = ASN1_TYPE_EMPTY, tpmkey = ASN1_TYPE_EMPTY;
char value_buf[16];
int value_buflen;
int emptyauth = 0;
unsigned int parent;

err = gnutls_pem_base64_decode_alloc("TSS2 KEY BLOB", fdata, &asn1);
if (err) {
Expand All @@ -45,9 +66,74 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_strerror(err));
return -EINVAL;
}
free(asn1.data);

err = asn1_array2tree(tpmkey_asn1_tab, &tpmkey_def, NULL);
if (err != ASN1_SUCCESS) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to create ASN.1 type for TPM2: %s\n"),
asn1_strerror(err));
goto out_asn1;
}

asn1_create_element(tpmkey_def, "TPMKey.TPMKey", &tpmkey);
err = asn1_der_decoding(&tpmkey, asn1.data, asn1.size, NULL);
if (err != ASN1_SUCCESS) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to decode TPM2 key ASN.1: %s\n"),
asn1_strerror(err));
goto out_tpmkey;
}
asn1_print_structure(stdout, tpmkey, "", ASN1_PRINT_ALL);

value_buflen = sizeof(value_buf);
err = asn1_read_value(tpmkey, "type", value_buf, &value_buflen);
if (err != ASN1_SUCCESS) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to identify type of TPM2 key: %s\n"),
asn1_strerror(err));
goto out_tpmkey;
}
if (strcmp(value_buf, "2.23.133.10.2")) {
vpn_progress(vpninfo, PRG_ERR,
_("Unsupported TPM2 key OID: %s\n"),
value_buf);
goto out_tpmkey;
}

value_buflen = sizeof(value_buf);
if (!asn1_read_value(tpmkey, "emptyAuth", value_buf, &value_buflen) ||
!strcmp(value_buf, "TRUE"))
emptyauth = 1;

memset(value_buf, 0, 4);
value_buflen = 4;
err = asn1_read_value(tpmkey, "parent", value_buf, &value_buflen);
if (err == ASN1_ELEMENT_NOT_FOUND)
parent = TPM_RH_OWNER;
else if (err != ASN1_SUCCESS) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to parse TPM2 key parent: %s\n"),
asn1_strerror(err));
goto out_tpmkey;
} else {
int i;
parent = 0;

for (i = 0; i < value_buflen; i++)
parent |= value_buf[value_buflen - i - 1] << (8 * i);
}
vpn_progress(vpninfo, PRG_DEBUG,
_("Parsed TPM2 key with parent %x, emptyauth %d\n"),
parent, emptyauth);

vpn_progress(vpninfo, PRG_ERR,
_("TPM2 not really implemented yet\n"));

out_tpmkey:
asn1_delete_structure(&tpmkey);
asn1_delete_structure(&tpmkey_def);
out_asn1:
free(asn1.data);
return -EINVAL;
}

Expand Down

0 comments on commit e1f2bb7

Please sign in to comment.