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;
|
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*,
|
METHOD(stroke_cred_t, load_ca, certificate_t*,
|
||||||
private_stroke_cred_t *this, char *filename)
|
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*,
|
METHOD(stroke_cred_t, load_peer, certificate_t*,
|
||||||
private_stroke_cred_t *this, char *filename)
|
private_stroke_cred_t *this, char *filename)
|
||||||
{
|
{
|
||||||
certificate_t *cert;
|
certificate_t *cert = NULL;
|
||||||
char path[PATH_MAX];
|
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));
|
smartcard_format_t format;
|
||||||
keyid = chunk_from_hex(chunk_skip(keyid, strlen("%smartcard:")), NULL);
|
char module[BUF_LEN], keyid[BUF_LEN];
|
||||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
u_int slot;
|
||||||
BUILD_PKCS11_KEYID, keyid, BUILD_END);
|
|
||||||
free(keyid.ptr);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -597,7 +684,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
|
|||||||
FILE *prompt)
|
FILE *prompt)
|
||||||
{
|
{
|
||||||
chunk_t sc = chunk_empty, secret = chunk_empty;
|
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;
|
private_key_t *key = NULL;
|
||||||
u_int slot;
|
u_int slot;
|
||||||
chunk_t chunk;
|
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;
|
mem_cred_t *mem = NULL;
|
||||||
callback_cred_t *cb = NULL;
|
callback_cred_t *cb = NULL;
|
||||||
pin_cb_data_t pin_data;
|
pin_cb_data_t pin_data;
|
||||||
enum {
|
smartcard_format_t format;
|
||||||
SC_FORMAT_SLOT_MODULE_KEYID,
|
|
||||||
SC_FORMAT_SLOT_KEYID,
|
|
||||||
SC_FORMAT_KEYID,
|
|
||||||
} format;
|
|
||||||
|
|
||||||
err_t ugh = extract_value(&sc, &line);
|
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);
|
snprintf(smartcard, sizeof(smartcard), "%.*s", (int)sc.len, sc.ptr);
|
||||||
smartcard[sizeof(smartcard) - 1] = '\0';
|
smartcard[sizeof(smartcard) - 1] = '\0';
|
||||||
|
|
||||||
/* parse slot and key id. Three formats are supported:
|
format = parse_smartcard(smartcard, &slot, module, keyid);
|
||||||
* - %smartcard<slot>@<module>:<keyid>
|
if (format == SC_FORMAT_INVALID)
|
||||||
* - %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
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
|
DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
|
||||||
" supported or invalid", line_nr);
|
" 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 */
|
/* unlock: smartcard needs the pin and potentially calls public set */
|
||||||
switch (format)
|
key = (private_key_t*)load_from_smartcard(format, slot, module, keyid,
|
||||||
{
|
CRED_PRIVATE_KEY, KEY_ANY);
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (mem)
|
if (mem)
|
||||||
{
|
{
|
||||||
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
|
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
|
||||||
|
|||||||
Reference in New Issue
Block a user