Refactored stroke smartcard token parsing, support module and slot in leftcert option

This commit is contained in:
Martin Willi
2012-10-24 13:07:53 +02:00
parent 36e47a409b
commit 2abe404927
+101 -62
View File
@@ -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);