Re: [openssl-dev] [RFC 1/2] engine: add new flag based method for loading engine keys

2016-11-16 Thread Dr. Stephen Henson
On Wed, Nov 16, 2016, James Bottomley wrote:

> The assumption in all the current engine code is that key_id can be
> passed as something like a file name.

Well no it's a null terminated string whose meaning is engine specific. In
some cases it is a key ID, in others it is a more complex string indicating
multiple parameters.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl

2016-11-16 Thread Blumenthal, Uri - 0553 - MITLL
Thank you! I think I understand. (Sounds like an ugly and hardly necessary 
complication to me – not to mention that there might not be a filesystem to 
keep those around, but…)
— 
Regards,
Uri


On 11/16/16, 5:06 PM, "openssl-dev on behalf of Dr. Stephen Henson" 
 wrote:

On Wed, Nov 16, 2016, Richard Levitte wrote:

> If I understand correctly, the intention is to avoid having to use
> ENGINE_load_private_key() directly or having to say '-keyform ENGINE'
> to the openssl commands, and to avoid having to remember some cryptic
> key identity to give with '-key'.  Instead of all that, just give the
> name of a .pem file with '-key' and if that file contains some kind of
> magic information that the engine can understand, it will dig out a
> reference to the hw protected key.
> 
> Many years ago, I was thinking of something along the same lines, but
> with a .pem file that would just have a few headers, holding the name
> of the intended engine and the key identity, something like this:
> 
> -BEGIN PRIVATE KEY-
> X-key-id: flarflarflar
> X-key-engine: foo
> -END PRIVATE KEY-
> 
> The intent was that the PEM code would be massaged to recognise these
> headers and would then use ENGINE_by_id() / ENGINE_load_private_key()
> with those data and that would be it.
> 

Yes me too. Though if you're doing that something like "ENGINE PRIVATE KEY"
or "OPENSSL ENGINE PRIVATE KEY" as just "PRIVATE KEY" is associated with
PKCS#8.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev



smime.p7s
Description: S/MIME cryptographic signature
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl

2016-11-16 Thread Dr. Stephen Henson
On Wed, Nov 16, 2016, Richard Levitte wrote:

> If I understand correctly, the intention is to avoid having to use
> ENGINE_load_private_key() directly or having to say '-keyform ENGINE'
> to the openssl commands, and to avoid having to remember some cryptic
> key identity to give with '-key'.  Instead of all that, just give the
> name of a .pem file with '-key' and if that file contains some kind of
> magic information that the engine can understand, it will dig out a
> reference to the hw protected key.
> 
> Many years ago, I was thinking of something along the same lines, but
> with a .pem file that would just have a few headers, holding the name
> of the intended engine and the key identity, something like this:
> 
> -BEGIN PRIVATE KEY-
> X-key-id: flarflarflar
> X-key-engine: foo
> -END PRIVATE KEY-
> 
> The intent was that the PEM code would be massaged to recognise these
> headers and would then use ENGINE_by_id() / ENGINE_load_private_key()
> with those data and that would be it.
> 

Yes me too. Though if you're doing that something like "ENGINE PRIVATE KEY"
or "OPENSSL ENGINE PRIVATE KEY" as just "PRIVATE KEY" is associated with
PKCS#8.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


Re: [openssl-dev] [RFC 1/2] engine: add new flag based method for loading engine keys

2016-11-16 Thread Salz, Rich
It is a heck of a lot easier for everyone if you make pull requests and not 
just mail big patches.  Can you do that?
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl

2016-11-16 Thread Richard Levitte
If I understand correctly, the intention is to avoid having to use
ENGINE_load_private_key() directly or having to say '-keyform ENGINE'
to the openssl commands, and to avoid having to remember some cryptic
key identity to give with '-key'.  Instead of all that, just give the
name of a .pem file with '-key' and if that file contains some kind of
magic information that the engine can understand, it will dig out a
reference to the hw protected key.

Many years ago, I was thinking of something along the same lines, but
with a .pem file that would just have a few headers, holding the name
of the intended engine and the key identity, something like this:

-BEGIN PRIVATE KEY-
X-key-id: flarflarflar
X-key-engine: foo
-END PRIVATE KEY-

The intent was that the PEM code would be massaged to recognise these
headers and would then use ENGINE_by_id() / ENGINE_load_private_key()
with those data and that would be it.

James, did I catch your intention about right?  I think that's
essentially what e_tpm.c does for loading keys, right?

Cheers,
Richard ( gotta love to see someone use "flarflarflar" as a key id ;-) )

In message <60f14e07-d0dc-486f-aff7-c74f5929b...@ll.mit.edu> on Wed, 16 Nov 
2016 15:56:05 +, "Blumenthal, Uri - 0553 - MITLL"  said:

uri> My apologies – I don’t fully understand “file based engine keys”. I 
thought the keys were either on a hardware device (a TPM, a PKCS#11-accessible 
HSM or smartcard, etc), or in a file. If a key is in a file – it’s not an 
“engine key”.
uri> 
uri> What am I missing, and what’s your use case(s)?
uri> — 
uri> Regards,
uri> Uri
uri> 
uri> 
uri> On 11/16/16, 10:46 AM, "openssl-dev on behalf of James Bottomley" 
 wrote:
uri> 
uri> [David Woodhouse told me that openssl-dev is a closed list, so the
uri> original messages got trashed.  This is a resend with apologies to
uri> David and Peter]
uri> 
uri> One of the principle problems of using TPM based keys is that there's
uri> no easy way of integrating them with standard file based keys.  This
uri> proposal adds a generic method for handling file based engine keys that
uri> can be loaded as PEM files.  Integration into the PEM loader requires a
uri> BIO based engine API callback which the first patch adds.  The second
uri> patch checks to see if the key can be loaded by any of the present
uri> engines.  Note that this requires that any engine which is to be used
uri> must be present and initialised via openssl.cnf.
uri> 
uri> I'll also post to this list the patch to openssl_tpm_engine that makes
uri> use if this infrastructure so the integration of the whole can be seen.
uri>  It should also be noted that gnutls has had this functionality since
uri> 2012.
uri> 
uri> The patch was done against 1.0.2h for easier testing and you can try it
uri> and the openssl_tpm_engine out (if you run openSUSE) here:
uri> 
uri> https://build.opensuse.org/project/show/home:jejb1:Tumbleweed
uri> 
uri> James
uri> 
uri> ---
uri> 
uri> James Bottomley (2):
uri>   engine: add new flag based method for loading engine keys
uri>   pem: load engine keys
uri> 
uri>  crypto/engine/eng_int.h  |  1 +
uri>  crypto/engine/eng_pkey.c | 38 ++
uri>  crypto/engine/engine.h   | 26 ++
uri>  crypto/pem/pem_pkey.c|  5 +
uri>  4 files changed, 70 insertions(+)
uri> 
uri> -- 
uri> openssl-dev mailing list
uri> To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev
uri> 
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


Re: [openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl

2016-11-16 Thread Blumenthal, Uri - 0553 - MITLL
My apologies – I don’t fully understand “file based engine keys”. I thought the 
keys were either on a hardware device (a TPM, a PKCS#11-accessible HSM or 
smartcard, etc), or in a file. If a key is in a file – it’s not an “engine key”.

What am I missing, and what’s your use case(s)?
— 
Regards,
Uri


On 11/16/16, 10:46 AM, "openssl-dev on behalf of James Bottomley" 
 wrote:

[David Woodhouse told me that openssl-dev is a closed list, so the
original messages got trashed.  This is a resend with apologies to
David and Peter]

One of the principle problems of using TPM based keys is that there's
no easy way of integrating them with standard file based keys.  This
proposal adds a generic method for handling file based engine keys that
can be loaded as PEM files.  Integration into the PEM loader requires a
BIO based engine API callback which the first patch adds.  The second
patch checks to see if the key can be loaded by any of the present
engines.  Note that this requires that any engine which is to be used
must be present and initialised via openssl.cnf.

I'll also post to this list the patch to openssl_tpm_engine that makes
use if this infrastructure so the integration of the whole can be seen.
 It should also be noted that gnutls has had this functionality since
2012.

The patch was done against 1.0.2h for easier testing and you can try it
and the openssl_tpm_engine out (if you run openSUSE) here:

https://build.opensuse.org/project/show/home:jejb1:Tumbleweed

James

---

James Bottomley (2):
  engine: add new flag based method for loading engine keys
  pem: load engine keys

 crypto/engine/eng_int.h  |  1 +
 crypto/engine/eng_pkey.c | 38 ++
 crypto/engine/engine.h   | 26 ++
 crypto/pem/pem_pkey.c|  5 +
 4 files changed, 70 insertions(+)

-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev



smime.p7s
Description: S/MIME cryptographic signature
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


[openssl-dev] [RFC 2/2] pem: load engine keys

2016-11-16 Thread James Bottomley
Before trying to process the PEM file, hand it to each of the
loaded engines to see if they can load it.  This uses the new
bio based callback, so the engine must be loaded and implement this
callback to be considered.

Signed-off-by: James Bottomley 
---
 crypto/pem/pem_pkey.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 04d6319..8d44d45 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -85,6 +85,11 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, 
pem_password_cb *cb,
 int slen;
 EVP_PKEY *ret = NULL;
 
+if (ENGINE_find_engine_load_key(NULL, &ret, (const char *)bp, cb, u,
+   ENGINE_LOAD_KEY_FLAG_BIO) == 1) {
+return ret;
+}
+
 if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
 return NULL;
 p = data;
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


[openssl-dev] [RFC 0/2] Proposal for seamless handling of TPM based RSA keys in openssl

2016-11-16 Thread James Bottomley
[David Woodhouse told me that openssl-dev is a closed list, so the
original messages got trashed.  This is a resend with apologies to
David and Peter]

One of the principle problems of using TPM based keys is that there's
no easy way of integrating them with standard file based keys.  This
proposal adds a generic method for handling file based engine keys that
can be loaded as PEM files.  Integration into the PEM loader requires a
BIO based engine API callback which the first patch adds.  The second
patch checks to see if the key can be loaded by any of the present
engines.  Note that this requires that any engine which is to be used
must be present and initialised via openssl.cnf.

I'll also post to this list the patch to openssl_tpm_engine that makes
use if this infrastructure so the integration of the whole can be seen.
 It should also be noted that gnutls has had this functionality since
2012.

The patch was done against 1.0.2h for easier testing and you can try it
and the openssl_tpm_engine out (if you run openSUSE) here:

https://build.opensuse.org/project/show/home:jejb1:Tumbleweed

James

---

James Bottomley (2):
  engine: add new flag based method for loading engine keys
  pem: load engine keys

 crypto/engine/eng_int.h  |  1 +
 crypto/engine/eng_pkey.c | 38 ++
 crypto/engine/engine.h   | 26 ++
 crypto/pem/pem_pkey.c|  5 +
 4 files changed, 70 insertions(+)

-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev


[openssl-dev] [RFC 1/2] engine: add new flag based method for loading engine keys

2016-11-16 Thread James Bottomley
The assumption in all the current engine code is that key_id can be
passed as something like a file name.  There are some new users that
actually want to pass a BIO, so add a new load_key method for engines
that takes a flag value.  The first defined flag is
ENGINE_LOAD_KEY_FLAG_BIO which means that the key_id is actually a bio
pointer.

Signed-off-by: James Bottomley 
---
 crypto/engine/eng_int.h  |  1 +
 crypto/engine/eng_pkey.c | 38 ++
 crypto/engine/engine.h   | 26 ++
 3 files changed, 65 insertions(+)

diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
index 46f163b..b65cc41 100644
--- a/crypto/engine/eng_int.h
+++ b/crypto/engine/eng_int.h
@@ -197,6 +197,7 @@ struct engine_st {
 ENGINE_CTRL_FUNC_PTR ctrl;
 ENGINE_LOAD_KEY_PTR load_privkey;
 ENGINE_LOAD_KEY_PTR load_pubkey;
+ENGINE_LOAD_KEY_FLAGS_PTR load_key_flags;
 ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
 const ENGINE_CMD_DEFN *cmd_defns;
 int flags;
diff --git a/crypto/engine/eng_pkey.c b/crypto/engine/eng_pkey.c
index 23580d9..124426f 100644
--- a/crypto/engine/eng_pkey.c
+++ b/crypto/engine/eng_pkey.c
@@ -64,6 +64,13 @@ int ENGINE_set_load_privkey_function(ENGINE *e,
 return 1;
 }
 
+int ENGINE_set_load_key_flags_function(ENGINE *e,
+  ENGINE_LOAD_KEY_FLAGS_PTR load_f)
+{
+e->load_key_flags = load_f;
+return 1;
+}
+
 int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
 {
 e->load_pubkey = loadpub_f;
@@ -88,6 +95,11 @@ ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const 
ENGINE *e)
 return e->load_pubkey;
 }
 
+ENGINE_LOAD_KEY_FLAGS_PTR ENGINE_get_load_key_flags_function(const ENGINE *e)
+{
+return e->load_key_flags;
+}
+
 ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
*e)
 {
@@ -184,3 +196,29 @@ int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
 return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
ui_method, callback_data);
 }
+
+int ENGINE_find_engine_load_key(ENGINE **e, EVP_PKEY **pkey, const char 
*key_id,
+pem_password_cb *cb, void *cb_data,
+unsigned int flags)
+{
+ENGINE *ep;
+int ret = 0;
+
+for (ep = ENGINE_get_first(); ep != NULL; ep = ENGINE_get_next(ep)) {
+if (!ep->load_key_flags)
+continue;
+if (ep->load_key_flags(ep, pkey, key_id, cb, cb_data, flags) == 1) {
+ret = 1;
+break;
+}
+   if (flags & ENGINE_LOAD_KEY_FLAG_BIO)
+(void)BIO_reset((BIO *)key_id);
+   ERR_clear_error();
+}
+if (e)
+*e = ep;
+else if (ep)
+ENGINE_free(ep);
+
+return ret;
+}
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
index bd7b591..49f6a55 100644
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -97,6 +97,7 @@
 # include 
 
 # include 
+# include 
 
 #ifdef  __cplusplus
 extern "C" {
@@ -338,6 +339,19 @@ typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, 
void *,
 typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
  UI_METHOD *ui_method,
  void *callback_data);
+
+/*
+ * This flag signals that the const char *key_id (3rd argument) actually
+ * points to a SSL BIO structure
+ */
+#define ENGINE_LOAD_KEY_FLAG_BIO   0x01
+
+/* Replacement load_key with flags and return code */
+typedef int (*ENGINE_LOAD_KEY_FLAGS_PTR)(ENGINE *, EVP_PKEY **,
+const char *,
+pem_password_cb *pwd_callback,
+void *callback_data,
+unsigned int flags);
 typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl,
STACK_OF(X509_NAME) *ca_dn,
X509 **pcert, EVP_PKEY **pkey,
@@ -565,6 +579,8 @@ int ENGINE_set_finish_function(ENGINE *e, 
ENGINE_GEN_INT_FUNC_PTR finish_f);
 int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
 int ENGINE_set_load_privkey_function(ENGINE *e,
  ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_key_flags_function(ENGINE *e,
+  ENGINE_LOAD_KEY_FLAGS_PTR loadpriv_f);
 int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
 int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
  ENGINE_SSL_CLIENT_CERT_PTR
@@ -611,6 +627,7 @@ ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const 
ENGINE *e);
 ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
 ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_fu

[openssl-dev] [PATCH] openssl tpm engine: add new openssl bio method for seamless loading of tpm keys

2016-11-16 Thread James Bottomley
Permits this engine to be used as part of the openssl pem
routines for loading TPM based keys.  To use this, the
tpm engine must be preloaded via the openssl.cnf file

Signed-off-by: James Bottomley 

diff --git a/e_tpm.c b/e_tpm.c
index 3e20f8e..9cb1d6c 100644
--- a/e_tpm.c
+++ b/e_tpm.c
@@ -43,13 +43,19 @@
 #ifndef OPENSSL_NO_HW
 #ifndef OPENSSL_NO_HW_TPM
 
+struct tpm_ui {
+UI_METHOD *ui_method;
+pem_password_cb *pem_cb;
+};
+
 /* engine specific functions */
 static int tpm_engine_destroy(ENGINE *);
 static int tpm_engine_init(ENGINE *);
 static int tpm_engine_finish(ENGINE *);
 static int tpm_engine_ctrl(ENGINE *, int, long, void *, void (*)());
 static EVP_PKEY *tpm_engine_load_key(ENGINE *, const char *, UI_METHOD *, void 
*);
-static char *tpm_engine_get_auth(UI_METHOD *, char *, int, char *, void *);
+static int tpm_engine_load_key_flags(ENGINE *, EVP_PKEY **, const char *, 
pem_password_cb *, void *, unsigned int);
+static char *tpm_engine_get_auth(struct tpm_ui *, char *, int, char *, void *);
 
 #ifndef OPENSSL_NO_RSA
 /* rsa functions */
@@ -212,6 +218,9 @@ static int bind_helper(ENGINE * e)
!ENGINE_set_ctrl_function(e, tpm_engine_ctrl) ||
!ENGINE_set_load_pubkey_function(e, tpm_engine_load_key) ||
!ENGINE_set_load_privkey_function(e, tpm_engine_load_key) ||
+#ifdef ENGINE_LOAD_KEY_FLAG_BIO
+!ENGINE_set_load_key_flags_function(e, tpm_engine_load_key_flags) 
||
+#endif
!ENGINE_set_cmd_defns(e, tpm_cmd_defns))
return 0;
 
@@ -244,7 +253,7 @@ void ENGINE_load_tpm(void)
ERR_clear_error();
 }
 
-int tpm_load_srk(UI_METHOD *ui, void *cb_data)
+int tpm_load_srk(struct tpm_ui *ui, void *cb_data)
 {
TSS_RESULT result;
UINT32 authusage;
@@ -451,8 +460,9 @@ err:
return 0;
 }
 
-static char *tpm_engine_get_auth(UI_METHOD *ui_method, char *auth, int maxlen,
-char *input_string, void *cb_data)
+static char *tpm_engine_get_auth_ui(UI_METHOD *ui_method, char *auth,
+   int maxlen, char *input_string,
+   void *cb_data)
 {
UI *ui;
 
@@ -479,6 +489,30 @@ static char *tpm_engine_get_auth(UI_METHOD *ui_method, 
char *auth, int maxlen,
return auth;
 }
 
+static char *tpm_engine_get_auth_pem(pem_password_cb *pem_cb, char *auth,
+   int maxlen, char *input_string,
+   void *cb_data)
+{
+   EVP_set_pw_prompt(input_string);
+   if (!pem_cb)
+   pem_cb = PEM_def_callback;
+   pem_cb(auth, maxlen, 0, cb_data);
+   EVP_set_pw_prompt(NULL);
+
+   return auth;
+}
+
+static char *tpm_engine_get_auth(struct tpm_ui *ui, char *auth,
+ int maxlen, char *input_string, void *cb_data)
+{
+   if (ui->ui_method)
+   return tpm_engine_get_auth_ui(ui->ui_method, auth, maxlen,
+ input_string, cb_data);
+   else
+   return tpm_engine_get_auth_pem(ui->pem_cb, auth, maxlen,
+  input_string, cb_data);
+}
+
 static int tpm_engine_finish(ENGINE * e)
 {
DBG("%s", __FUNCTION__);
@@ -575,8 +609,19 @@ int fill_out_rsa_object(RSA *rsa, TSS_HKEY hKey)
return 1;
 }
 
-static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id,
-UI_METHOD *ui, void *cb_data)
+static inline int tpm_flag_is_bio(unsigned int flags)
+{
+#ifdef ENGINE_LOAD_KEY_FLAG_BIO
+   return flags & ENGINE_LOAD_KEY_FLAG_BIO;
+#else
+   return 0;
+#endif
+}
+
+static int tpm_engine_load_key_core(ENGINE *e, EVP_PKEY **ppkey,
+ const char *key_id,
+  struct tpm_ui *ui,
+  void *cb_data, unsigned int flags)
 {
ASN1_OCTET_STRING *blobstr;
TSS_HKEY hKey;
@@ -591,37 +636,55 @@ static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const 
char *key_id,
 
if (!key_id) {
TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_PASSED_NULL_PARAMETER);
-   return NULL;
-   }
-
-   if (!tpm_load_srk(ui, cb_data)) {
-   TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_SRK_LOAD_FAILED);
-   return NULL;
+   return 0;
}
 
-   if ((bf = BIO_new_file(key_id, "r")) == NULL) {
-   TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
-  TPM_R_FILE_NOT_FOUND);
-   return NULL;
+   if (tpm_flag_is_bio(flags)) {
+   bf = (BIO *)key_id;
+   } else {
+   if ((bf = BIO_new_file(key_id, "r")) == NULL) {
+   TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY,
+  TPM_R_FILE_NOT_FOUND);
+   return 0;
+   }
}
 
blobstr = PEM_ASN1_read_bio((void *)d2i_ASN1_O