aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@HansenPartnership.com>2020-05-29 14:16:42 -0700
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2020-05-29 14:16:42 -0700
commit85edaa409a2e64d20a705240b5167ef0ca74ff4e (patch)
tree0daaf5b952154b6ea111d09d66fbca2e96e26cf8
parent50b4f9446f03ca87e71966fef60ef35ce454bd7b (diff)
downloadopenssl-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.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/crypto.c b/crypto.c
index e37ef63..e68a32b 100644
--- a/crypto.c
+++ b/crypto.c
@@ -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;