This patch adds RSA signing for TPM2 keys. There's a limitation to the
way TPM2 does signing: it must recognise the OID for the signature.
That fails for the MD5-SHA1 signatures of the TLS/SSL certificate
verification protocol, so I'm using RSA_Decrypt for both signing
(encryption) and decryption ... meaning that this only works with TPM
decryption keys. It is possible to use the prior code, which preserved
the distinction of signing and decryption keys, but only at the expense
of not being able to support SSL or TLS lower than 1.2
Signed-off-by: James Bottomley
---
v2: - use TPM2_RSA_Decrypt for both decryption and signing operations
- Add authority processing
- Add TPM internal key creation
- allow persistent parents
- update to use transient connections to the TPM
---
Makefile.am | 12 +-
create_tpm2_key.c | 451 +++
e_tpm2.c | 559 ++
tpm2-asn.h| 59 ++
tpm2-common.c | 175 +
tpm2-common.h | 10 +
6 files changed, 1264 insertions(+), 2 deletions(-)
create mode 100644 create_tpm2_key.c
create mode 100644 e_tpm2.c
create mode 100644 tpm2-asn.h
create mode 100644 tpm2-common.c
create mode 100644 tpm2-common.h
diff --git a/Makefile.am b/Makefile.am
index 6695656..fb4f529 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,12 +2,20 @@ SUBDIRS=. test
EXTRA_DIST = README openssl.cnf.sample
-openssl_engine_LTLIBRARIES=libtpm.la
-bin_PROGRAMS=create_tpm_key
+openssl_engine_LTLIBRARIES=libtpm.la libtpm2.la
+bin_PROGRAMS=create_tpm_key create_tpm2_key
openssl_enginedir=@libdir@/openssl/engines
libtpm_la_LIBADD=-lcrypto -lc -ltspi
libtpm_la_SOURCES=e_tpm.c e_tpm.h e_tpm_err.c
+libtpm2_la_LIBADD=-lcrypto -lc -ltss
+libtpm2_la_SOURCES=e_tpm2.c tpm2-common.c
+libtpm2_la_CFLAGS=-g -Werror
+
create_tpm_key_SOURCES=create_tpm_key.c
create_tpm_key_LDADD=-ltspi
+
+create_tpm2_key_SOURCES=create_tpm2_key.c tpm2-common.c
+create_tpm2_key_LDADD=-lcrypto -ltss
+create_tpm2_key_CFLAGS=-Werror
diff --git a/create_tpm2_key.c b/create_tpm2_key.c
new file mode 100644
index 000..ca3b38f
--- /dev/null
+++ b/create_tpm2_key.c
@@ -0,0 +1,451 @@
+/*
+ *
+ * Copyright (C) 2016 James Bottomley
+ *
+ * GPLv2
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "tpm2-asn.h"
+#include "tpm2-common.h"
+
+static struct option long_options[] = {
+ {"auth", 0, 0, 'a'},
+ {"help", 0, 0, 'h'},
+ {"key-size", 1, 0, 's'},
+ {"name-scheme", 1, 0, 'n'},
+ {"parent-handle", 1, 0, 'p'},
+ {"wrap", 1, 0, 'w'},
+ {0, 0, 0, 0}
+};
+
+static TPM_ALG_ID name_alg = TPM_ALG_SHA256;
+static int name_alg_size = SHA256_DIGEST_SIZE;
+
+void
+usage(char *argv0)
+{
+ fprintf(stderr, "\t%s: create a TPM key and write it to disk\n"
+ "\tusage: %s [options] \n\n"
+ "\tOptions:\n"
+ "\t\t-a|--auth require a password for the key [NO]\n"
+ "\t\t-h|--help print this help message\n"
+ "\t\t-s|--key-size key size in bits [2048]\n"
+ "\t\t-n|--name-scheme name algorithm to use sha1 [sha256]
sha384 sha512\n"
+ "\t\t-p|--parent-handle persistent handle of parent key\n"
+ "\t\t-w|--wrap [file] wrap an existing openssl PEM key\n"
+ "\nReport bugs to %s\n",
+ argv0, argv0, PACKAGE_BUGREPORT);
+ exit(-1);
+}
+
+void
+openssl_print_errors()
+{
+ ERR_load_ERR_strings();
+ ERR_load_crypto_strings();
+ ERR_print_errors_fp(stderr);
+}
+
+int
+openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
+ BYTE *privkey, int privkey_len, int empty_auth,
+ TPM_HANDLE parent)
+{
+ TSSLOADABLE tssl;
+ BIO *outb;
+
+ /* clear structure so as not to have to set optional parameters */
+ memset(, 0, sizeof(tssl));
+ if ((outb = BIO_new_file(file, "w")) == NULL) {
+fprintf(stderr, "Error opening file for write: %s\n", file);
+ return 1;
+ }
+ tssl.type = OBJ_txt2obj(OID_loadableKey, 1);
+ tssl.emptyAuth = empty_auth;
+ if ((parent & 0xff00) == 0x8100) {
+ tssl.parent = ASN1_INTEGER_new();
+ ASN1_INTEGER_set(tssl.parent, parent);
+ }
+ tssl.pubkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(tssl.pubkey, pubkey, pubkey_len);
+ tssl.privkey = ASN1_OCTET_STRING_new();
+ ASN1_STRING_set(tssl.privkey, privkey, privkey_len);
+
+ PEM_write_bio_TSSLOADABLE(outb, );
+ BIO_free(outb);
+ return 0;
+}
+
+EVP_PKEY *
+openssl_read_key(char *filename)
+{
+BIO *b = NULL;