diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2020-05-29 14:16:42 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2020-05-29 14:16:42 -0700 |
commit | 85edaa409a2e64d20a705240b5167ef0ca74ff4e (patch) | |
tree | 0daaf5b952154b6ea111d09d66fbca2e96e26cf8 | |
parent | 50b4f9446f03ca87e71966fef60ef35ce454bd7b (diff) | |
download | openssl-pkcs11-export-85edaa409a2e64d20a705240b5167ef0ca74ff4e.tar.gz |
crypto.c: check that the password is correct for login
With PKCS11 tokens, if C_Login returns OK that confirms the password
is correct. However, with engine keys, the password may or may not be
checked in ENGINE_load_private_key() so try to perform a signing
operation if that function returns a key.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r-- | crypto.c | 40 |
1 files changed, 39 insertions, 1 deletions
@@ -186,12 +186,46 @@ ui_reader(UI *ui, UI_STRING *uis) return 0; } -int pem_cb (char *buf, int size, int rwflag, void *pin) +static int pem_cb (char *buf, int size, int rwflag, void *pin) { strncpy(buf, pin, size); return strlen(pin); } +static EVP_PKEY *check_signature(EVP_PKEY *pk) +{ + EVP_PKEY_CTX *ctx; + unsigned char result[1024], hash[SHA256_DIGEST_LENGTH]; + size_t siglen; + int ret; + + if (!pk) + return pk; + + ctx = EVP_PKEY_CTX_new(pk, NULL); + if (!ctx) { + ERR_print_errors_fp(stderr); + goto err_free_pkey; + } + + EVP_PKEY_sign_init(ctx); + + siglen = sizeof(result); + ret = EVP_PKEY_sign(ctx, result, &siglen, hash, sizeof(hash)); + EVP_PKEY_CTX_free(ctx); + + if (ret != 1 || siglen == 0) { + ERR_print_errors_fp(stderr); + goto err_free_pkey; + } + return pk; + + err_free_pkey: + + EVP_PKEY_free(pk); + return NULL; +} + int crypto_load_private_key(int sec_num, const unsigned char *pin, int pin_len) { EVP_PKEY *pkey = NULL; @@ -234,6 +268,10 @@ int crypto_load_private_key(int sec_num, const unsigned char *pin, int pin_len) /* cast discards const which is respected by ui_read */ pkey = ENGINE_load_private_key(e, priv, ui, (void *)auth); ENGINE_finish(e); + /* engine's don't have to return an error if the + * password is wrong, so do a signing operation to + * flush out and incorrect password */ + pkey = check_signature(pkey); } else { FILE *file; wordexp_t w; |