diff options
Diffstat (limited to 'src/libtpmtss/plugins')
-rw-r--r-- | src/libtpmtss/plugins/tpm/Makefile.am | 1 | ||||
-rw-r--r-- | src/libtpmtss/plugins/tpm/Makefile.in | 6 | ||||
-rw-r--r-- | src/libtpmtss/plugins/tpm/tpm_cert.c | 97 | ||||
-rw-r--r-- | src/libtpmtss/plugins/tpm/tpm_cert.h | 38 | ||||
-rw-r--r-- | src/libtpmtss/plugins/tpm/tpm_plugin.c | 11 |
5 files changed, 149 insertions, 4 deletions
diff --git a/src/libtpmtss/plugins/tpm/Makefile.am b/src/libtpmtss/plugins/tpm/Makefile.am index 281281022..27db5cc01 100644 --- a/src/libtpmtss/plugins/tpm/Makefile.am +++ b/src/libtpmtss/plugins/tpm/Makefile.am @@ -15,6 +15,7 @@ endif libstrongswan_tpm_la_SOURCES = \ tpm_plugin.h tpm_plugin.c \ + tpm_cert.h tpm_cert.c \ tpm_private_key.h tpm_private_key.c \ tpm_rng.h tpm_rng.c diff --git a/src/libtpmtss/plugins/tpm/Makefile.in b/src/libtpmtss/plugins/tpm/Makefile.in index a12c18a35..e03e73656 100644 --- a/src/libtpmtss/plugins/tpm/Makefile.in +++ b/src/libtpmtss/plugins/tpm/Makefile.in @@ -138,8 +138,8 @@ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @MONOLITHIC_FALSE@libstrongswan_tpm_la_DEPENDENCIES = \ @MONOLITHIC_FALSE@ $(top_builddir)/src/libtpmtss/libtpmtss.la -am_libstrongswan_tpm_la_OBJECTS = tpm_plugin.lo tpm_private_key.lo \ - tpm_rng.lo +am_libstrongswan_tpm_la_OBJECTS = tpm_plugin.lo tpm_cert.lo \ + tpm_private_key.lo tpm_rng.lo libstrongswan_tpm_la_OBJECTS = $(am_libstrongswan_tpm_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -465,6 +465,7 @@ AM_CFLAGS = \ libstrongswan_tpm_la_SOURCES = \ tpm_plugin.h tpm_plugin.c \ + tpm_cert.h tpm_cert.c \ tpm_private_key.h tpm_private_key.c \ tpm_rng.h tpm_rng.c @@ -558,6 +559,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpm_cert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpm_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpm_private_key.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tpm_rng.Plo@am__quote@ diff --git a/src/libtpmtss/plugins/tpm/tpm_cert.c b/src/libtpmtss/plugins/tpm/tpm_cert.c new file mode 100644 index 000000000..248da7e53 --- /dev/null +++ b/src/libtpmtss/plugins/tpm/tpm_cert.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2017 Andreas Steffen + * HSR Hochschule für Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "tpm_cert.h" + +#include <tpm_tss.h> + +#include <utils/debug.h> + + +/** + * See header. + */ +certificate_t *tpm_cert_load(certificate_type_t type, va_list args) +{ + tpm_tss_t *tpm; + chunk_t keyid = chunk_empty, pin = chunk_empty, data = chunk_empty; + certificate_t *cert; + char handle_str[4]; + size_t len; + uint32_t hierarchy = 0x40000001; /* TPM_RH_OWNER */ + uint32_t handle; + bool success; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_PKCS11_KEYID: + keyid = va_arg(args, chunk_t); + continue; + case BUILD_PKCS11_SLOT: + hierarchy = va_arg(args, int); + continue; + case BUILD_PKCS11_MODULE: + va_arg(args, char*); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + /* convert keyid into 32 bit TPM key object handle */ + if (!keyid.len) + { + return NULL; + } + len = min(keyid.len, 4); + memset(handle_str, 0x00, 4); + memcpy(handle_str + 4 - len, keyid.ptr + keyid.len - len, len); + handle = untoh32(handle_str); + + /* try to find a TPM 2.0 */ + tpm = tpm_tss_probe(TPM_VERSION_2_0); + if (!tpm) + { + DBG1(DBG_LIB, "no TPM 2.0 found"); + return NULL; + } + success = tpm->get_data(tpm, hierarchy, handle, pin, &data); + tpm->destroy(tpm); + + if (!success) + { + DBG1(DBG_LIB, "loading certificate from TPM NV index 0x%08x failed", + handle); + return NULL; + } + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_BLOB_ASN1_DER, data, BUILD_END); + free(data.ptr); + + if (!cert) + { + DBG1(DBG_LIB, "parsing certificate from TPM NV index 0x%08x failed", + handle); + return NULL; + } + DBG1(DBG_LIB, "loaded certificate from TPM NV index 0x%08x", handle); + + return cert; +} diff --git a/src/libtpmtss/plugins/tpm/tpm_cert.h b/src/libtpmtss/plugins/tpm/tpm_cert.h new file mode 100644 index 000000000..a6cb34554 --- /dev/null +++ b/src/libtpmtss/plugins/tpm/tpm_cert.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2017 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup tpm_cert tpm_cert + * @{ @ingroup tpm + */ + +#ifndef TPM_CERT_H_ +#define TPM_CERT_H_ + +#include <credentials/certificates/certificate.h> + +/** + * Load a specific certificate from a TPM + * + * Requires a BUILD_PKCS11_KEYID argument, and optionally a BUILD_PKCS11_SLOT + * to designate the NV storage hierarchy. + * + * @param type certificate type, must be CERT_X509 + * @param args variable argument list, containing BUILD_PKCS11_KEYID. + * @return loaded certificate, or NULL on failure + */ +certificate_t *tpm_cert_load(certificate_type_t type, va_list args); + +#endif /** TPM_CERT_H_ @}*/ diff --git a/src/libtpmtss/plugins/tpm/tpm_plugin.c b/src/libtpmtss/plugins/tpm/tpm_plugin.c index b9a4c12a8..e98899852 100644 --- a/src/libtpmtss/plugins/tpm/tpm_plugin.c +++ b/src/libtpmtss/plugins/tpm/tpm_plugin.c @@ -15,6 +15,7 @@ #include "tpm_plugin.h" #include "tpm_private_key.h" +#include "tpm_cert.h" #include "tpm_rng.h" #include <library.h> @@ -50,13 +51,19 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(PRIVKEY, tpm_private_key_connect, FALSE), PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), }; - static plugin_feature_t f[countof(f_rng) + countof(f_privkey)] = {}; - + static plugin_feature_t f_cert[] = { + PLUGIN_REGISTER(CERT_DECODE, tpm_cert_load, FALSE), + PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), + PLUGIN_DEPENDS(CERT_DECODE, CERT_X509), + }; + static plugin_feature_t f[countof(f_rng) + countof(f_privkey) + + countof(f_cert)] = {}; static int count = 0; if (!count) { plugin_features_add(f, f_privkey, countof(f_privkey), &count); + plugin_features_add(f, f_cert, countof(f_cert), &count); if (lib->settings->get_bool(lib->settings, "%s.plugins.tpm.use_rng", FALSE, lib->ns)) |