Allow engine keys to be a public key file

Some engines have corresponding public key load methods, so use those
if the normal load of the public key fails.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
diff --git a/crypto.c b/crypto.c
index e68a32b..87b0945 100644
--- a/crypto.c
+++ b/crypto.c
@@ -96,6 +96,7 @@
 	FILE *file;
 	EVP_PKEY *pkey;
 	wordexp_t w;
+	const char *engine = cache_get_by_secnum(sec_num, "engine", NULL);
 
 	wordexp(pub, &w, 0);
 	file = fopen(w.we_wordv[0], "r");
@@ -108,11 +109,24 @@
 	}
 	pkey = PEM_read_PUBKEY(file, NULL, NULL, NULL);
 	if (!pkey) {
-		fprintf(stderr, "failed to read public key %s:\n", pub);
-		ERR_print_errors_fp(stderr);
-		return -1;
-	}
+		if (engine) {
+			ENGINE *e;
 
+			ENGINE_load_builtin_engines();
+			e = ENGINE_by_id(engine);
+			if (!e)
+				goto err;
+			ENGINE_init(e);
+			pkey = ENGINE_load_public_key(e, pub, NULL, NULL);
+			if (!pkey)
+				goto err;
+		} else {
+		err:
+			fprintf(stderr, "failed to read public key %s:\n", pub);
+			ERR_print_errors_fp(stderr);
+			return -1;
+		}
+	}
 	return populate_public_key(sec_num, pkey);
 }