aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2018-10-12 01:01:18 +0100
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2018-10-31 22:14:55 -0700
commit413d96519468bdc081596786a4bf29805efcb06b (patch)
tree6f02cdf1a29d1ea95c7bfdbe3ac3c4c13bf372eb
parent7bdc1cca370659ef83fd09157083dfa2edfd24e4 (diff)
downloadopenssl_tpm2_engine-413d96519468bdc081596786a4bf29805efcb06b.tar.gz
Allow TSS2 PRIVATE KEY and TSS2 KEY BLOB ASN.1 to diverge
... and indeed do so. Make the pubkey and parent non-optional, for a start, but leave the type field alone for now. The explicit tag of the policy field can change because it's harmles to do so. Signed-off-by: David Woodhouse <dwmw2@infradead.org> [jejb: plumb policy in correctly] Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--create_tpm2_key.c2
-rw-r--r--e_tpm2.c58
-rw-r--r--tpm2-asn.h24
3 files changed, 62 insertions, 22 deletions
diff --git a/create_tpm2_key.c b/create_tpm2_key.c
index 2c71ed3..06bcb84 100644
--- a/create_tpm2_key.c
+++ b/create_tpm2_key.c
@@ -236,7 +236,7 @@ openssl_write_tpmfile(const char *file, BYTE *pubkey, int pubkey_len,
BYTE *privkey, int privkey_len, int empty_auth,
TPM_HANDLE parent, STACK_OF(TSSOPTPOLICY) *sk)
{
- TSSLOADABLE tssl;
+ TSSPRIVKEY tssl;
BIO *outb;
/* clear structure so as not to have to set optional parameters */
diff --git a/e_tpm2.c b/e_tpm2.c
index f440d16..fd0ed1c 100644
--- a/e_tpm2.c
+++ b/e_tpm2.c
@@ -271,13 +271,13 @@ static int tpm2_engine_load_nvkey(ENGINE *e, EVP_PKEY **ppkey,
}
static int tpm2_engine_load_key_policy(struct app_data *app_data,
- TSSLOADABLE *tssl)
+ STACK_OF(TSSOPTPOLICY) *st_policy)
{
struct policy_command *command;
TSSOPTPOLICY *policy;
int i, commands_len;
- app_data->num_commands = sk_TSSOPTPOLICY_num(tssl->policy);
+ app_data->num_commands = sk_TSSOPTPOLICY_num(st_policy);
if (app_data->num_commands <= 0)
return 1;
@@ -287,7 +287,7 @@ static int tpm2_engine_load_key_policy(struct app_data *app_data,
return 0;
for (i = 0; i < app_data->num_commands; i++) {
- policy = sk_TSSOPTPOLICY_value(tssl->policy, i);
+ policy = sk_TSSOPTPOLICY_value(st_policy, i);
if (!policy)
return 0;
@@ -317,13 +317,19 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
EVP_PKEY *pkey;
TPM2B_PUBLIC p;
BIO *bf;
- TSSLOADABLE *tssl;
+ TSSLOADABLE *tssl = NULL;
+ TSSPRIVKEY *tpk = NULL;
BYTE *buffer;
INT32 size;
struct app_data *app_data;
char oid[128];
int empty_auth, version = 0;
const int nvkey_len = strlen(nvprefix);
+ ASN1_OBJECT *type;
+ ASN1_INTEGER *parent;
+ ASN1_OCTET_STRING *pubkey;
+ STACK_OF(TSSOPTPOLICY) *policy;
+ ASN1_OCTET_STRING *privkey;
if (!key_id && !bio) {
fprintf(stderr, "key_id or bio is NULL\n");
@@ -351,18 +357,32 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
return 0;
}
- tssl = PEM_read_bio_TSSPRIVKEY(bf, NULL, NULL, NULL);
- if (tssl) {
+ tpk = PEM_read_bio_TSSPRIVKEY(bf, NULL, NULL, NULL);
+ if (tpk) {
version = 1;
+ type = tpk->type;
+ empty_auth = tpk->emptyAuth;
+ parent = tpk->parent;
+ pubkey = tpk->pubkey;
+ privkey = tpk->privkey;
+ policy = tpk->policy;
} else {
BIO_seek(bf, 0);
tssl = PEM_read_bio_TSSLOADABLE(bf, NULL, NULL, NULL);
+ if (tssl) {
+ type = tssl->type;
+ empty_auth = tssl->emptyAuth;
+ parent = tssl->parent;
+ pubkey = tssl->pubkey;
+ privkey = tssl->privkey;
+ policy = tssl->policy;
+ }
}
if (!bio)
BIO_free(bf);
- if (!tssl) {
+ if (!tssl && !tpk) {
if (ppkey)
fprintf(stderr, "Failed to parse file %s\n", key_id);
return 0;
@@ -370,10 +390,11 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
if (!ppkey) {
TSSLOADABLE_free(tssl);
+ TSSPRIVKEY_free(tpk);
return 1;
}
- if (OBJ_obj2txt(oid, sizeof(oid), tssl->type, 1) == 0) {
+ if (OBJ_obj2txt(oid, sizeof(oid), type, 1) == 0) {
fprintf(stderr, "Failed to parse object type\n");
goto err;
}
@@ -402,25 +423,23 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
app_data->version = version;
app_data->dir = tpm2_set_unique_tssdir();
- if (tssl->parent)
- app_data->parent = ASN1_INTEGER_get(tssl->parent);
+ if (parent)
+ app_data->parent = ASN1_INTEGER_get(parent);
else
/* older keys have absent parent */
app_data->parent = TPM_RH_OWNER;
- empty_auth = tssl->emptyAuth;
-
- app_data->priv = OPENSSL_malloc(tssl->privkey->length);
+ app_data->priv = OPENSSL_malloc(privkey->length);
if (!app_data->priv)
goto err_free;
- app_data->priv_len = tssl->privkey->length;
- memcpy(app_data->priv, tssl->privkey->data, app_data->priv_len);
+ app_data->priv_len = privkey->length;
+ memcpy(app_data->priv, privkey->data, app_data->priv_len);
- app_data->pub = OPENSSL_malloc(tssl->pubkey->length);
+ app_data->pub = OPENSSL_malloc(pubkey->length);
if (!app_data->pub)
goto err_free;
- app_data->pub_len = tssl->pubkey->length;
- memcpy(app_data->pub, tssl->pubkey->data, app_data->pub_len);
+ app_data->pub_len = pubkey->length;
+ memcpy(app_data->pub, pubkey->data, app_data->pub_len);
buffer = app_data->pub;
size = app_data->pub_len;
TPM2B_PUBLIC_Unmarshal(&p, &buffer, &size, FALSE);
@@ -440,10 +459,11 @@ static int tpm2_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
if (!(p.publicArea.objectAttributes.val & TPMA_OBJECT_USERWITHAUTH))
app_data->req_policy_session = 1;
- if (!tpm2_engine_load_key_policy(app_data, tssl))
+ if (!tpm2_engine_load_key_policy(app_data, policy))
goto err_free_key;
TSSLOADABLE_free(tssl);
+ TSSPRIVKEY_free(tpk);
tpm2_bind_key_to_engine(pkey, app_data);
diff --git a/tpm2-asn.h b/tpm2-asn.h
index 5c78cdd..341edb5 100644
--- a/tpm2-asn.h
+++ b/tpm2-asn.h
@@ -68,6 +68,15 @@ typedef struct {
ASN1_OCTET_STRING *privkey;
} TSSLOADABLE;
+typedef struct {
+ ASN1_OBJECT *type;
+ ASN1_BOOLEAN emptyAuth;
+ STACK_OF(TSSOPTPOLICY) *policy;
+ ASN1_INTEGER *parent;
+ ASN1_OCTET_STRING *pubkey;
+ ASN1_OCTET_STRING *privkey;
+} TSSPRIVKEY;
+
/* the two type oids are in the TCG namespace 2.23.133; we choose an
* unoccupied child (10) for keytype file and two values:
* 1 : Key that is directly loadable
@@ -88,13 +97,24 @@ ASN1_SEQUENCE(TSSLOADABLE) = {
IMPLEMENT_ASN1_FUNCTIONS(TSSLOADABLE);
+ASN1_SEQUENCE(TSSPRIVKEY) = {
+ ASN1_SIMPLE(TSSPRIVKEY, type, ASN1_OBJECT),
+ ASN1_EXP_OPT(TSSPRIVKEY, emptyAuth, ASN1_BOOLEAN, 0),
+ ASN1_EXP_SEQUENCE_OF_OPT(TSSPRIVKEY, policy, TSSOPTPOLICY, 1),
+ ASN1_SIMPLE(TSSPRIVKEY, parent, ASN1_INTEGER),
+ ASN1_SIMPLE(TSSPRIVKEY, pubkey, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(TSSPRIVKEY, privkey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(TSSPRIVKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(TSSPRIVKEY);
+
/* This is the PEM guard tag */
#define TSSLOADABLE_PEM_STRING "TSS2 KEY BLOB"
#define TSSPRIVKEY_PEM_STRING "TSS2 PRIVATE KEY"
static IMPLEMENT_PEM_write_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE)
static IMPLEMENT_PEM_read_bio(TSSLOADABLE, TSSLOADABLE, TSSLOADABLE_PEM_STRING, TSSLOADABLE)
-static IMPLEMENT_PEM_write_bio(TSSPRIVKEY, TSSLOADABLE, TSSPRIVKEY_PEM_STRING, TSSLOADABLE)
-static IMPLEMENT_PEM_read_bio(TSSPRIVKEY, TSSLOADABLE, TSSPRIVKEY_PEM_STRING, TSSLOADABLE)
+static IMPLEMENT_PEM_write_bio(TSSPRIVKEY, TSSPRIVKEY, TSSPRIVKEY_PEM_STRING, TSSPRIVKEY)
+static IMPLEMENT_PEM_read_bio(TSSPRIVKEY, TSSPRIVKEY, TSSPRIVKEY_PEM_STRING, TSSPRIVKEY)
#endif