+/**
+ * rsa_engine_get_priv_key() - read a private key from given engine
+ *
+ * @keydir: Key prefix
+ * @name Name of key
+ * @engine Engine to use
+ * @evpp Returns EVP_PKEY object, or NULL on failure
+ * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
+ */
+static int rsa_engine_get_priv_key(const char *keydir, const char *name,
+ const char *keyfile,
+ ENGINE *engine, EVP_PKEY **evpp)
+{
+ const char *engine_id;
+ char key_id[1024];
+ EVP_PKEY *key = NULL;
+
+ if (!evpp)
+ return -EINVAL;
+
+ engine_id = ENGINE_get_id(engine);
+
+ if (engine_id && !strcmp(engine_id, "pkcs11")) {
+ if (!keydir && !name) {
+ fprintf(stderr, "Please use 'keydir' with PKCS11\n");
+ return -EINVAL;
+ }
+ if (keydir)
+ if (strstr(keydir, "object="))
+ snprintf(key_id, sizeof(key_id),
+ "pkcs11:%s;type=private",
+ keydir);
+ else
+ snprintf(key_id, sizeof(key_id),
+ "pkcs11:%s;object=%s;type=private",
+ keydir, name);
+ else
+ snprintf(key_id, sizeof(key_id),
+ "pkcs11:object=%s;type=private",
+ name);
+ } else if (engine_id) {
+ if (keydir && name)
+ snprintf(key_id, sizeof(key_id),
+ "%s%s",
+ keydir, name);
+ else if (name)
+ snprintf(key_id, sizeof(key_id),
+ "%s",
+ name ? name : "");
+ else if (keyfile)
+ snprintf(key_id, sizeof(key_id), "%s", keyfile);
+ else
+ return -EINVAL;
+
+ } else {
+ fprintf(stderr, "Engine not supported\n");
+ return -ENOTSUP;
+ }
+
+ key = ENGINE_load_private_key(engine, key_id, NULL, NULL);
+ if (!key)
+ return rsa_err("Failure loading private key from engine");
+
+ *evpp = key;
+
+ return 0;
+}
+
+/**
+ * rsa_get_priv_key() - read a private key
+ *
+ * @keydir: Directory containing the key (PEM file) or key prefix (engine)
+ * @name Name of key
+ * @engine Engine to use for signing
+ * @evpp Returns EVP_PKEY object, or NULL on failure
+ * @return 0 if ok, -ve on error (in which case *evpp will be set to NULL)
+ */
+static int rsa_get_priv_key(const char *keydir, const char *name,
+ const char *keyfile, ENGINE *engine, EVP_PKEY **evpp)
+{
+ if (engine)
+ return rsa_engine_get_priv_key(keydir, name, keyfile, engine,
+ evpp);
+ return rsa_pem_get_priv_key(keydir, name, keyfile, evpp);
+}
+