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 <j...@linux.vnet.ibm.com> --- 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 <openssl/symhacks.h> # include <openssl/x509.h> +# include <openssl/pem.h> #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_function(const ENGINE *e); ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_FLAGS_PTR ENGINE_get_load_key_flags_function(const ENGINE *e); ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e); ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); @@ -671,6 +688,15 @@ int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, UI_METHOD *ui_method, void *callback_data); /* + * Given a key_id, this method iterates over all present engines to + * see if any can handle it. It's functionality depends on the engine + * implementing e->load_key_flags. + */ +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); + +/* * This returns a pointer for the current ENGINE structure that is (by * default) performing any RSA operations. The value returned is an * incremented reference, so it should be free'd (ENGINE_finish) before it is -- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev