aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c13
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.h3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c154
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c150
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h3
5 files changed, 168 insertions, 155 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index 22bbf6dc7..d187c06ed 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -49,6 +49,11 @@ struct private_openssl_ec_private_key_t {
EC_KEY *ec;
/**
+ * TRUE if the key is from an OpenSSL ENGINE and might not be readable
+ */
+ bool engine;
+
+ /**
* reference count
*/
refcount_t ref;
@@ -226,6 +231,11 @@ METHOD(private_key_t, get_encoding, bool,
{
u_char *p;
+ if (this->engine)
+ {
+ return FALSE;
+ }
+
switch (type)
{
case PRIVKEY_ASN1_DER:
@@ -307,7 +317,7 @@ static private_openssl_ec_private_key_t *create_empty(void)
/*
* See header.
*/
-private_key_t *openssl_ec_private_key_create(EVP_PKEY *key)
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key, bool engine)
{
private_openssl_ec_private_key_t *this;
EC_KEY *ec;
@@ -320,6 +330,7 @@ private_key_t *openssl_ec_private_key_create(EVP_PKEY *key)
}
this = create_empty();
this->ec = ec;
+ this->engine = engine;
return &this->public.key;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
index 84314f671..56c59cfc8 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.h
@@ -67,8 +67,9 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
* Wrap an EVP_PKEY object of type EVP_PKEY_EC
*
* @param key EVP_PKEY_EC key object (adopted)
+ * @param engine whether the key was loaded via an engine
* @return loaded key, NULL on failure
*/
-private_key_t *openssl_ec_private_key_create(EVP_PKEY *key);
+private_key_t *openssl_ec_private_key_create(EVP_PKEY *key, bool engine);
#endif /** OPENSSL_EC_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index ab73d718f..2f05b2b3d 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -301,11 +301,11 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
{
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
- return openssl_rsa_private_key_create(key);
+ return openssl_rsa_private_key_create(key, FALSE);
#endif
#ifndef OPENSSL_NO_ECDSA
case EVP_PKEY_EC:
- return openssl_ec_private_key_create(key);
+ return openssl_ec_private_key_create(key, FALSE);
#endif
default:
EVP_PKEY_free(key);
@@ -316,6 +316,152 @@ static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
return NULL;
}
+#ifndef OPENSSL_NO_ENGINE
+/**
+ * Login to engine with a PIN specified for a keyid
+ */
+static bool login(ENGINE *engine, chunk_t keyid)
+{
+ enumerator_t *enumerator;
+ shared_key_t *shared;
+ identification_t *id;
+ chunk_t key;
+ char pin[64];
+ bool found = FALSE, success = FALSE;
+
+ id = identification_create_from_encoding(ID_KEY_ID, keyid);
+ enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
+ SHARED_PIN, id, NULL);
+ while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
+ {
+ found = TRUE;
+ key = shared->get_key(shared);
+ if (snprintf(pin, sizeof(pin),
+ "%.*s", (int)key.len, key.ptr) >= sizeof(pin))
+ {
+ continue;
+ }
+ if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
+ {
+ success = TRUE;
+ break;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "setting PIN on engine failed");
+ }
+ }
+ enumerator->destroy(enumerator);
+ id->destroy(id);
+ if (!found)
+ {
+ DBG1(DBG_CFG, "no PIN found for %#B", &keyid);
+ }
+ return success;
+}
+#endif /* OPENSSL_NO_ENGINE */
+
+/**
+ * Load private key via engine
+ */
+static private_key_t *openssl_private_key_connect(key_type_t type,
+ va_list args)
+{
+#ifndef OPENSSL_NO_ENGINE
+ char *engine_id = NULL;
+ char keyname[BUF_LEN];
+ chunk_t keyid = chunk_empty;;
+ EVP_PKEY *key;
+ ENGINE *engine;
+ int slot = -1;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_PKCS11_KEYID:
+ keyid = va_arg(args, chunk_t);
+ continue;
+ case BUILD_PKCS11_SLOT:
+ slot = va_arg(args, int);
+ continue;
+ case BUILD_PKCS11_MODULE:
+ engine_id = va_arg(args, char*);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ if (!keyid.len || keyid.len > 40)
+ {
+ return NULL;
+ }
+
+ memset(keyname, 0, sizeof(keyname));
+ if (slot != -1)
+ {
+ snprintf(keyname, sizeof(keyname), "%d:", slot);
+ }
+ if (sizeof(keyname) - strlen(keyname) <= keyid.len * 4 / 3 + 1)
+ {
+ return NULL;
+ }
+ chunk_to_hex(keyid, keyname + strlen(keyname), FALSE);
+
+ if (!engine_id)
+ {
+ engine_id = lib->settings->get_str(lib->settings,
+ "%s.plugins.openssl.engine_id", "pkcs11", lib->ns);
+ }
+ engine = ENGINE_by_id(engine_id);
+ if (!engine)
+ {
+ DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
+ return NULL;
+ }
+ if (!ENGINE_init(engine))
+ {
+ DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id);
+ ENGINE_free(engine);
+ return NULL;
+ }
+ if (!login(engine, keyid))
+ {
+ DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
+ ENGINE_free(engine);
+ return NULL;
+ }
+ key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
+ if (!key)
+ {
+ DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
+ "engine '%s'", keyname, engine_id);
+ ENGINE_free(engine);
+ return NULL;
+ }
+ ENGINE_free(engine);
+
+ switch (EVP_PKEY_base_id(key))
+ {
+#ifndef OPENSSL_NO_RSA
+ case EVP_PKEY_RSA:
+ return openssl_rsa_private_key_create(key, TRUE);
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ case EVP_PKEY_EC:
+ return openssl_ec_private_key_create(key, TRUE);
+#endif
+ default:
+ EVP_PKEY_free(key);
+ break;
+ }
+#endif /* OPENSSL_NO_ENGINE */
+ return NULL;
+}
+
METHOD(plugin_t, get_name, char*,
private_openssl_plugin_t *this)
{
@@ -469,8 +615,6 @@ METHOD(plugin_t, get_features, int,
/* RSA private/public key loading */
PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
- PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE),
- PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
@@ -554,6 +698,8 @@ METHOD(plugin_t, get_features, int,
/* generic key loader */
PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_REGISTER(PRIVKEY, openssl_private_key_connect, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
PLUGIN_REGISTER(RNG, openssl_rng_create),
PLUGIN_PROVIDE(RNG, RNG_STRONG),
PLUGIN_PROVIDE(RNG, RNG_WEAK),
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
index 54ecf2542..fd624e6a3 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
@@ -27,9 +27,6 @@
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif /* OPENSSL_NO_ENGINE */
/**
* Public exponent to use for key generation.
@@ -386,7 +383,7 @@ error:
/*
* See header
*/
-private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key)
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine)
{
private_openssl_rsa_private_key_t *this;
RSA *rsa;
@@ -399,6 +396,7 @@ private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key)
}
this = create_empty();
this->rsa = rsa;
+ this->engine = engine;
return &this->public.key;
}
@@ -502,148 +500,4 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
return NULL;
}
-#ifndef OPENSSL_NO_ENGINE
-/**
- * Login to engine with a PIN specified for a keyid
- */
-static bool login(ENGINE *engine, chunk_t keyid)
-{
- enumerator_t *enumerator;
- shared_key_t *shared;
- identification_t *id;
- chunk_t key;
- char pin[64];
- bool found = FALSE, success = FALSE;
-
- id = identification_create_from_encoding(ID_KEY_ID, keyid);
- enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
- SHARED_PIN, id, NULL);
- while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
- {
- found = TRUE;
- key = shared->get_key(shared);
- if (snprintf(pin, sizeof(pin),
- "%.*s", (int)key.len, key.ptr) >= sizeof(pin))
- {
- continue;
- }
- if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
- {
- success = TRUE;
- break;
- }
- else
- {
- DBG1(DBG_CFG, "setting PIN on engine failed");
- }
- }
- enumerator->destroy(enumerator);
- id->destroy(id);
- if (!found)
- {
- DBG1(DBG_CFG, "no PIN found for %#B", &keyid);
- }
- return success;
-}
-#endif /* OPENSSL_NO_ENGINE */
-
-/*
- * See header.
- */
-openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
- va_list args)
-{
-#ifndef OPENSSL_NO_ENGINE
- private_openssl_rsa_private_key_t *this;
- char *engine_id = NULL;
- char keyname[64];
- chunk_t keyid = chunk_empty;;
- EVP_PKEY *key;
- ENGINE *engine;
- int slot = -1;
-
- while (TRUE)
- {
- switch (va_arg(args, builder_part_t))
- {
- case BUILD_PKCS11_KEYID:
- keyid = va_arg(args, chunk_t);
- continue;
- case BUILD_PKCS11_SLOT:
- slot = va_arg(args, int);
- continue;
- case BUILD_PKCS11_MODULE:
- engine_id = va_arg(args, char*);
- continue;
- case BUILD_END:
- break;
- default:
- return NULL;
- }
- break;
- }
- if (!keyid.len || keyid.len > 40)
- {
- return NULL;
- }
-
- memset(keyname, 0, sizeof(keyname));
- if (slot != -1)
- {
- snprintf(keyname, sizeof(keyname), "%d:", slot);
- }
- if (sizeof(keyname) - strlen(keyname) <= keyid.len * 4 / 3 + 1)
- {
- return NULL;
- }
- chunk_to_hex(keyid, keyname + strlen(keyname), FALSE);
-
- if (!engine_id)
- {
- engine_id = lib->settings->get_str(lib->settings,
- "%s.plugins.openssl.engine_id", "pkcs11", lib->ns);
- }
- engine = ENGINE_by_id(engine_id);
- if (!engine)
- {
- DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
- return NULL;
- }
- if (!ENGINE_init(engine))
- {
- DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id);
- ENGINE_free(engine);
- return NULL;
- }
- if (!login(engine, keyid))
- {
- DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
- ENGINE_free(engine);
- return NULL;
- }
- key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
- if (!key)
- {
- DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
- "engine '%s'", keyname, engine_id);
- ENGINE_free(engine);
- return NULL;
- }
- ENGINE_free(engine);
-
- this = create_empty();
- this->rsa = EVP_PKEY_get1_RSA(key);
- this->engine = TRUE;
- if (!this->rsa)
- {
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-#else /* OPENSSL_NO_ENGINE */
- return NULL;
-#endif /* OPENSSL_NO_ENGINE */
-}
-
#endif /* OPENSSL_NO_RSA */
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
index 34ce4c776..783181c1d 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_private_key.h
@@ -67,9 +67,10 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_load(key_type_t type,
* Wrap an EVP_PKEY object of type EVP_PKEY_RSA
*
* @param key EVP_PKEY_RSA key object (adopted)
+ * @param engine whether the key was loaded via an engine
* @return loaded key, NULL on failure
*/
-private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key);
+private_key_t *openssl_rsa_private_key_create(EVP_PKEY *key, bool engine);
/**
* Connect to a RSA private key on a smartcard.