[RFC 2/2] engine: add "any" engine mechanism and make it the default
James Bottomley
James.Bottomley at HansenPartnership.com
Thu Oct 26 18:45:13 AEDT 2017
If openssl cannot load the private key, chances are it's an engine key
(or a corrupt file), so try processing it via any engine first before
concluding corruption.
Signed-off-by: James Bottomley <James.Bottomley at HansenPartnership.com>
---
ssh-add.c | 6 ++++--
ssh-engine.c | 51 +++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/ssh-add.c b/ssh-add.c
index d85bcc7ec..b8706866a 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -459,8 +459,10 @@ do_file(int agent_fd, int deleting, int key_only, char *file, int qflag)
if (delete_file(agent_fd, file, key_only, qflag) == -1)
return -1;
} else {
- if (add_file(agent_fd, file, key_only, qflag) == -1)
- return -1;
+ if (add_file(agent_fd, file, key_only, qflag) == -1) {
+ if (add_engine_key(agent_fd, file, "any") < 0)
+ return -1;
+ }
}
return 0;
}
diff --git a/ssh-engine.c b/ssh-engine.c
index f4673e4ee..53fd1a004 100644
--- a/ssh-engine.c
+++ b/ssh-engine.c
@@ -37,29 +37,23 @@ ui_read(UI *ui, UI_STRING *uis)
return d->ret;
}
-int
-engine_process_add(char *engine, char *file, char *pin,
- struct sshkey **k)
+static int
+engine_process_add_internal(ENGINE *e, char *file, char *pin,
+ struct sshkey **k)
{
EVP_PKEY *pk;
- ENGINE *e;
struct sshkey *key;
int ret;
UI_METHOD *ui;
EVP_PKEY_CTX *ctx;
char hash[SHA256_DIGEST_LENGTH], result[1024];
size_t siglen;
+ const char *engine = ENGINE_get_name(e);
struct ui_data d;
verbose("%s: add provider=%s, key=%s", __func__, engine, file);
ret = SSH_ERR_INTERNAL_ERROR;
- e = ENGINE_by_id(engine);
- if (!e) {
- verbose("%s: failed to get engine %s", __func__, engine);
- ERR_print_errors_fp(stderr);
- return ret;
- }
ui = UI_create_method("ssh-agent password writer");
if (!ui) {
@@ -152,3 +146,40 @@ engine_process_add(char *engine, char *file, char *pin,
verbose("%s: returning %d", __func__, ret);
return ret;
}
+
+int
+engine_process_add(char *engine, char *file, char *pin,
+ struct sshkey **k)
+{
+ ENGINE *e;
+
+ if (strcmp(engine, "any") != 0) {
+ int ret;
+
+ e = ENGINE_by_id(engine);
+ if (!e) {
+ verbose("%s: failed to get engine %s", __func__, engine);
+ ERR_print_errors_fp(stderr);
+ return SSH_ERR_INTERNAL_ERROR;
+ }
+ ret = engine_process_add_internal(e, file, pin, k);
+ ENGINE_free(e);
+ return ret;
+ }
+
+ /* this is the any engine case */
+
+ for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
+ int ret;
+
+ if (!ENGINE_get_load_privkey_function(e))
+ continue;
+
+ ret = engine_process_add_internal(e, file, pin, k);
+
+ if (ret == 1 || ret == SSH_ERR_KEY_WRONG_PASSPHRASE)
+ return ret;
+ }
+
+ return SSH_ERR_INTERNAL_ERROR;
+}
--
2.12.3
More information about the openssh-unix-dev
mailing list