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@xxxxxxxxxxxxxxxxxxxxx> --- 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 _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev