]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Parse TPM2 ASN.1 blob
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 3 Oct 2018 14:46:26 +0000 (15:46 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Mon, 8 Oct 2018 19:18:19 +0000 (20:18 +0100)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
configure.ac
gnutls_tpm2.c

index 55376d46e0c03884b56f691a1eec03ce5228d87f..365100623742acd3f430643d72368aca671311c5 100644 (file)
@@ -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)'])
        ;;
 
     *)
index f7ef826666a5941ea82375f40c994c8b159b15a5..0d640e15bab857171ff3b99401d9cd94522d6e8f 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <gnutls/gnutls.h>
 #include "openconnect-internal.h"
-
+#include <libtasn1.h>
 #include "gnutls.h"
 
 #ifdef HAVE_TSS2
 
 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) {
@@ -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;
 }