Refactored stroke smartcard token parsing, support module and slot in leftcert option
This commit is contained in:
@@ -82,6 +82,89 @@ struct private_stroke_cred_t {
|
||||
bool cachecrl;
|
||||
};
|
||||
|
||||
/**
|
||||
* Kind of smartcard specifier token
|
||||
*/
|
||||
typedef enum {
|
||||
SC_FORMAT_SLOT_MODULE_KEYID,
|
||||
SC_FORMAT_SLOT_KEYID,
|
||||
SC_FORMAT_KEYID,
|
||||
SC_FORMAT_INVALID,
|
||||
} smartcard_format_t;
|
||||
|
||||
/**
|
||||
* Parse a smartcard specifier token
|
||||
*/
|
||||
static smartcard_format_t parse_smartcard(char *smartcard, u_int *slot,
|
||||
char module[BUF_LEN], char keyid[BUF_LEN])
|
||||
{
|
||||
/* The token has one of the following three formats:
|
||||
* - %smartcard<slot>@<module>:<keyid>
|
||||
* - %smartcard<slot>:<keyid>
|
||||
* - %smartcard:<keyid>
|
||||
*/
|
||||
char buf[BUF_LEN], *pos;
|
||||
|
||||
if (sscanf(smartcard, "%%smartcard%u@%127s", slot, buf) == 2)
|
||||
{
|
||||
pos = strchr(buf, ':');
|
||||
if (!pos)
|
||||
{
|
||||
return SC_FORMAT_INVALID;
|
||||
}
|
||||
*pos++ = '\0';
|
||||
snprintf(module, BUF_LEN, "%s", buf);
|
||||
snprintf(keyid, BUF_LEN, "%s", pos);
|
||||
return SC_FORMAT_SLOT_MODULE_KEYID;
|
||||
}
|
||||
if (sscanf(smartcard, "%%smartcard%u:%63s", slot, keyid) == 2)
|
||||
{
|
||||
return SC_FORMAT_SLOT_KEYID;
|
||||
}
|
||||
if (sscanf(smartcard, "%%smartcard:%63s", keyid) == 1)
|
||||
{
|
||||
return SC_FORMAT_KEYID;
|
||||
}
|
||||
return SC_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a credential from a smartcard
|
||||
*/
|
||||
static certificate_t *load_from_smartcard(smartcard_format_t format,
|
||||
u_int slot, char *module, char *keyid,
|
||||
credential_type_t type, int subtype)
|
||||
{
|
||||
chunk_t chunk;
|
||||
void *cred;
|
||||
|
||||
chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
|
||||
switch (format)
|
||||
{
|
||||
case SC_FORMAT_SLOT_MODULE_KEYID:
|
||||
cred = lib->creds->create(lib->creds, type, subtype,
|
||||
BUILD_PKCS11_SLOT, slot,
|
||||
BUILD_PKCS11_MODULE, module,
|
||||
BUILD_PKCS11_KEYID, chunk, BUILD_END);
|
||||
break;
|
||||
case SC_FORMAT_SLOT_KEYID:
|
||||
cred = lib->creds->create(lib->creds, type, subtype,
|
||||
BUILD_PKCS11_SLOT, slot,
|
||||
BUILD_PKCS11_KEYID, chunk, BUILD_END);
|
||||
break;
|
||||
case SC_FORMAT_KEYID:
|
||||
cred = lib->creds->create(lib->creds, type, subtype,
|
||||
BUILD_PKCS11_KEYID, chunk, BUILD_END);
|
||||
break;
|
||||
default:
|
||||
cred = NULL;
|
||||
break;
|
||||
}
|
||||
free(chunk.ptr);
|
||||
|
||||
return cred;
|
||||
}
|
||||
|
||||
METHOD(stroke_cred_t, load_ca, certificate_t*,
|
||||
private_stroke_cred_t *this, char *filename)
|
||||
{
|
||||
@@ -131,17 +214,21 @@ METHOD(stroke_cred_t, load_ca, certificate_t*,
|
||||
METHOD(stroke_cred_t, load_peer, certificate_t*,
|
||||
private_stroke_cred_t *this, char *filename)
|
||||
{
|
||||
certificate_t *cert;
|
||||
certificate_t *cert = NULL;
|
||||
char path[PATH_MAX];
|
||||
chunk_t keyid;
|
||||
|
||||
if (strneq(filename, "%smartcard:", strlen("%smartcard:")))
|
||||
if (strneq(filename, "%smartcard", strlen("%smartcard")))
|
||||
{
|
||||
keyid = chunk_create(filename, strlen(filename));
|
||||
keyid = chunk_from_hex(chunk_skip(keyid, strlen("%smartcard:")), NULL);
|
||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_PKCS11_KEYID, keyid, BUILD_END);
|
||||
free(keyid.ptr);
|
||||
smartcard_format_t format;
|
||||
char module[BUF_LEN], keyid[BUF_LEN];
|
||||
u_int slot;
|
||||
|
||||
format = parse_smartcard(filename, &slot, module, keyid);
|
||||
if (format != SC_FORMAT_INVALID)
|
||||
{
|
||||
cert = (certificate_t*)load_from_smartcard(format,
|
||||
slot, module, keyid, CRED_CERTIFICATE, CERT_X509);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -597,7 +684,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
|
||||
FILE *prompt)
|
||||
{
|
||||
chunk_t sc = chunk_empty, secret = chunk_empty;
|
||||
char smartcard[64], keyid[64], module[64], *pos;
|
||||
char smartcard[BUF_LEN], keyid[BUF_LEN], module[BUF_LEN];
|
||||
private_key_t *key = NULL;
|
||||
u_int slot;
|
||||
chunk_t chunk;
|
||||
@@ -606,11 +693,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
|
||||
mem_cred_t *mem = NULL;
|
||||
callback_cred_t *cb = NULL;
|
||||
pin_cb_data_t pin_data;
|
||||
enum {
|
||||
SC_FORMAT_SLOT_MODULE_KEYID,
|
||||
SC_FORMAT_SLOT_KEYID,
|
||||
SC_FORMAT_KEYID,
|
||||
} format;
|
||||
smartcard_format_t format;
|
||||
|
||||
err_t ugh = extract_value(&sc, &line);
|
||||
|
||||
@@ -627,33 +710,8 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
|
||||
snprintf(smartcard, sizeof(smartcard), "%.*s", (int)sc.len, sc.ptr);
|
||||
smartcard[sizeof(smartcard) - 1] = '\0';
|
||||
|
||||
/* 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)
|
||||
{
|
||||
pos = strchr(module, ':');
|
||||
if (!pos)
|
||||
{
|
||||
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is "
|
||||
"invalid", line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
*pos = '\0';
|
||||
strncpy(keyid, pos + 1, sizeof(keyid));
|
||||
format = SC_FORMAT_SLOT_MODULE_KEYID;
|
||||
}
|
||||
else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
|
||||
{
|
||||
format = SC_FORMAT_SLOT_KEYID;
|
||||
}
|
||||
else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
|
||||
{
|
||||
format = SC_FORMAT_KEYID;
|
||||
}
|
||||
else
|
||||
format = parse_smartcard(smartcard, &slot, module, keyid);
|
||||
if (format == SC_FORMAT_INVALID)
|
||||
{
|
||||
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
|
||||
" supported or invalid", line_nr);
|
||||
@@ -700,27 +758,8 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
|
||||
}
|
||||
|
||||
/* unlock: smartcard needs the pin and potentially calls public set */
|
||||
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, chunk, 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, chunk, BUILD_END);
|
||||
break;
|
||||
case SC_FORMAT_KEYID:
|
||||
key = lib->creds->create(lib->creds,
|
||||
CRED_PRIVATE_KEY, KEY_ANY,
|
||||
BUILD_PKCS11_KEYID, chunk, BUILD_END);
|
||||
break;
|
||||
}
|
||||
key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
|
||||
CRED_PRIVATE_KEY, KEY_ANY);
|
||||
if (mem)
|
||||
{
|
||||
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
|
||||
|
||||
Reference in New Issue
Block a user