Support module names in %smartcard specifier, streamlined smartcard building
This commit is contained in:
@@ -929,9 +929,14 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
|
||||
else if (match("PIN", &token))
|
||||
{
|
||||
chunk_t sc = chunk_empty, secret = chunk_empty;
|
||||
char smartcard[32], keyid[22], pin[32];
|
||||
char smartcard[64], keyid[64], pin[64], module[64], *pos;
|
||||
private_key_t *key;
|
||||
u_int slot;
|
||||
enum {
|
||||
SC_FORMAT_SLOT_MODULE_KEYID,
|
||||
SC_FORMAT_SLOT_KEYID,
|
||||
SC_FORMAT_KEYID,
|
||||
} format;
|
||||
|
||||
err_t ugh = extract_value(&sc, &line);
|
||||
|
||||
@@ -948,16 +953,31 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
|
||||
snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr);
|
||||
smartcard[sizeof(smartcard) - 1] = '\0';
|
||||
|
||||
/* parse slot and key id. only two formats are supported.
|
||||
* first try %smartcard<slot>:<keyid> */
|
||||
if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
|
||||
/* parse slot and key id. Three formats are supported:
|
||||
* - %smartcard<slot>@<module>:<keyid>
|
||||
* - %smartcard<slot>:<keyid>
|
||||
* - %smartcard:<keyid>
|
||||
*/
|
||||
if (sscanf(smartcard, "%%smartcard%u@%s", &slot, module) == 2)
|
||||
{
|
||||
snprintf(smartcard, sizeof(smartcard), "%u:%s", slot, keyid);
|
||||
pos = strchr(module, ':');
|
||||
if (!pos)
|
||||
{
|
||||
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is "
|
||||
"invalid", line_nr);
|
||||
goto error;
|
||||
}
|
||||
*pos = '\0';
|
||||
strcpy(keyid, pos + 1);
|
||||
format = SC_FORMAT_SLOT_MODULE_KEYID;
|
||||
}
|
||||
else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
|
||||
{
|
||||
format = SC_FORMAT_SLOT_KEYID;
|
||||
}
|
||||
/* then try %smartcard:<keyid> */
|
||||
else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
|
||||
{
|
||||
snprintf(smartcard, sizeof(smartcard), "%s", keyid);
|
||||
format = SC_FORMAT_KEYID;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -980,11 +1000,30 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
|
||||
snprintf(pin, sizeof(pin), "%.*s", secret.len, secret.ptr);
|
||||
pin[sizeof(pin) - 1] = '\0';
|
||||
|
||||
/* we assume an RSA key */
|
||||
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
BUILD_SMARTCARD_KEYID, smartcard,
|
||||
BUILD_SMARTCARD_PIN, pin, BUILD_END);
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case SC_FORMAT_SLOT_MODULE_KEYID:
|
||||
key = lib->creds->create(lib->creds,
|
||||
CRED_PRIVATE_KEY, KEY_ANY,
|
||||
BUILD_PKCS11_SLOT, slot,
|
||||
BUILD_PKCS11_MODULE, module,
|
||||
BUILD_PKCS11_KEYID, keyid,
|
||||
BUILD_PKCS11_PIN, pin, BUILD_END);
|
||||
break;
|
||||
case SC_FORMAT_SLOT_KEYID:
|
||||
key = lib->creds->create(lib->creds,
|
||||
CRED_PRIVATE_KEY, KEY_ANY,
|
||||
BUILD_PKCS11_SLOT, slot,
|
||||
BUILD_PKCS11_KEYID, keyid,
|
||||
BUILD_PKCS11_PIN, pin, BUILD_END);
|
||||
break;
|
||||
case SC_FORMAT_KEYID:
|
||||
key = lib->creds->create(lib->creds,
|
||||
CRED_PRIVATE_KEY, KEY_ANY,
|
||||
BUILD_PKCS11_KEYID, keyid,
|
||||
BUILD_PKCS11_PIN, pin, BUILD_END);
|
||||
break;
|
||||
}
|
||||
if (key)
|
||||
{
|
||||
DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr);
|
||||
|
||||
@@ -45,8 +45,10 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
|
||||
"BUILD_PATHLEN",
|
||||
"BUILD_X509_FLAG",
|
||||
"BUILD_REVOKED_ENUMERATOR",
|
||||
"BUILD_SMARTCARD_KEYID",
|
||||
"BUILD_SMARTCARD_PIN",
|
||||
"BUILD_PKCS11_MODULE",
|
||||
"BUILD_PKCS11_SLOT",
|
||||
"BUILD_PKCS11_KEYID",
|
||||
"BUILD_PKCS11_PIN",
|
||||
"BUILD_RSA_MODULUS",
|
||||
"BUILD_RSA_PUB_EXP",
|
||||
"BUILD_RSA_PRIV_EXP",
|
||||
|
||||
@@ -103,10 +103,14 @@ enum builder_part_t {
|
||||
BUILD_X509_FLAG,
|
||||
/** enumerator_t over (chunk_t serial, time_t date, crl_reason_t reason) */
|
||||
BUILD_REVOKED_ENUMERATOR,
|
||||
/** key ID of a key on a smartcard, null terminated char* ([slot:]keyid) */
|
||||
BUILD_SMARTCARD_KEYID,
|
||||
/** pin to access a key on a smartcard, null terminated char* */
|
||||
BUILD_SMARTCARD_PIN,
|
||||
/** friendly name of a PKCS#11 module, null terminated char* */
|
||||
BUILD_PKCS11_MODULE,
|
||||
/** slot specifier for a token in a PKCS#11 module, int */
|
||||
BUILD_PKCS11_SLOT,
|
||||
/** key ID of a key on a token, null terminated char* */
|
||||
BUILD_PKCS11_KEYID,
|
||||
/** pin to access a token, null terminated char* */
|
||||
BUILD_PKCS11_PIN,
|
||||
/** modulus (n) of a RSA key, chunk_t */
|
||||
BUILD_RSA_MODULUS,
|
||||
/** public exponent (e) of a RSA key, chunk_t */
|
||||
|
||||
@@ -318,7 +318,7 @@ plugin_t *openssl_plugin_create()
|
||||
(builder_function_t)openssl_rsa_private_key_load);
|
||||
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
(builder_function_t)openssl_rsa_private_key_gen);
|
||||
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
|
||||
lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
|
||||
(builder_function_t)openssl_rsa_private_key_connect);
|
||||
lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
|
||||
(builder_function_t)openssl_rsa_public_key_load);
|
||||
|
||||
@@ -451,21 +451,28 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
|
||||
{
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
private_openssl_rsa_private_key_t *this;
|
||||
char *keyid = NULL, *pin = NULL;
|
||||
char *keyid = NULL, *pin = NULL, *engine_id = NULL;
|
||||
char keyname[64];
|
||||
EVP_PKEY *key;
|
||||
char *engine_id;
|
||||
ENGINE *engine;
|
||||
int slot = -1;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
switch (va_arg(args, builder_part_t))
|
||||
{
|
||||
case BUILD_SMARTCARD_KEYID:
|
||||
case BUILD_PKCS11_KEYID:
|
||||
keyid = va_arg(args, char*);
|
||||
continue;
|
||||
case BUILD_SMARTCARD_PIN:
|
||||
case BUILD_PKCS11_PIN:
|
||||
pin = va_arg(args, char*);
|
||||
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:
|
||||
@@ -478,8 +485,20 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
engine_id = lib->settings->get_str(lib->settings,
|
||||
if (slot == -1)
|
||||
{
|
||||
snprintf(keyname, sizeof(keyname), "%s", keyid);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(keyname, sizeof(keyname), "%d:%s", slot, keyid);
|
||||
}
|
||||
|
||||
if (!engine_id)
|
||||
{
|
||||
engine_id = lib->settings->get_str(lib->settings,
|
||||
"libstrongswan.plugins.openssl.engine_id", "pkcs11");
|
||||
}
|
||||
engine = ENGINE_by_id(engine_id);
|
||||
if (!engine)
|
||||
{
|
||||
@@ -499,11 +518,11 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
key = ENGINE_load_private_key(engine, keyid, NULL, 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'", keyid, engine_id);
|
||||
"engine '%s'", keyname, engine_id);
|
||||
ENGINE_free(engine);
|
||||
return NULL;
|
||||
}
|
||||
@@ -512,6 +531,11 @@ openssl_rsa_private_key_t *openssl_rsa_private_key_connect(key_type_t type,
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user