From: Tobias Brunner Date: Fri, 18 Nov 2016 15:40:34 +0000 (+0100) Subject: swanctl: Add `token` secrets for keys on tokens/smartcards X-Git-Tag: 5.5.2dr5~9^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d2e3ff8e0c1a9e1382c9bd7424690c800958c112;p=thirdparty%2Fstrongswan.git swanctl: Add `token` secrets for keys on tokens/smartcards --- diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c index 8360178936..848d8512c2 100644 --- a/src/swanctl/commands/load_creds.c +++ b/src/swanctl/commands/load_creds.c @@ -568,6 +568,93 @@ static void load_containers(load_ctx_t *ctx, char *type, char *dir) } } +/** + * Load a single private key on a token over vici + */ +static bool load_token(load_ctx_t *ctx, char *name, char *pin) +{ + vici_req_t *req; + vici_res_t *res; + enumerator_t *enumerator; + char *key, *value, *id; + bool ret = TRUE; + + req = vici_begin("load-token"); + + enumerator = ctx->cfg->create_key_value_enumerator(ctx->cfg, "secrets.%s", + name); + while (enumerator->enumerate(enumerator, &key, &value)) + { + vici_add_key_valuef(req, key, "%s", value); + } + enumerator->destroy(enumerator); + + if (pin) + { + vici_add_key_valuef(req, "pin", "%s", pin); + } + res = vici_submit(req, ctx->conn); + if (!res) + { + fprintf(stderr, "load-token request failed: %s\n", strerror(errno)); + return FALSE; + } + if (ctx->format & COMMAND_FORMAT_RAW) + { + vici_dump(res, "load-token reply", ctx->format & COMMAND_FORMAT_PRETTY, + stdout); + } + else if (!streq(vici_find_str(res, "no", "success"), "yes")) + { + fprintf(stderr, "loading '%s' failed: %s\n", + name, vici_find_str(res, "", "errmsg")); + ret = FALSE; + } + else + { + id = vici_find_str(res, "", "id"); + printf("loaded key %s from token [keyid: %s]\n", name, id); + free(ctx->keys->remove(ctx->keys, id)); + } + vici_free_res(res); + return ret; +} + +/** + * Load keys from tokens + */ +static void load_tokens(load_ctx_t *ctx) +{ + enumerator_t *enumerator; + char *section, *pin = NULL, prompt[128]; + + enumerator = ctx->cfg->create_section_enumerator(ctx->cfg, "secrets"); + while (enumerator->enumerate(enumerator, §ion)) + { + if (strpfx(section, "token")) + { + if (!ctx->noprompt && + !ctx->cfg->get_str(ctx->cfg, "secrets.%s.pin", NULL, section)) + { +#ifdef HAVE_GETPASS + snprintf(prompt, sizeof(prompt), "PIN for %s: ", section); + pin = strdupnull(getpass(prompt)); +#endif + } + load_token(ctx, section, pin); + if (pin) + { + memwipe(pin, strlen(pin)); + free(pin); + pin = NULL; + } + } + } + enumerator->destroy(enumerator); +} + + + /** * Load a single secret over VICI */ @@ -591,6 +678,7 @@ static bool load_secret(load_ctx_t *ctx, char *section) "bliss", "pkcs8", "pkcs12", + "token", }; for (i = 0; i < countof(types); i++) @@ -842,6 +930,8 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format, load_containers(&ctx, "pkcs12", SWANCTL_PKCS12DIR); + load_tokens(&ctx); + enumerator = cfg->create_section_enumerator(cfg, "secrets"); while (enumerator->enumerate(enumerator, §ion)) { diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index 8ddc9f750b..caae41e887 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -918,6 +918,22 @@ secrets.pkcs12.file = secrets.pkcs12.secret Value of decryption passphrase for PKCS#12 container. +secrets.token { # } + Definition for a private key that's stored on a token/smartcard. + +secrets.token.handle = + Hex-encoded CKA_ID of the private key on the token. + +secrets.token.slot = + Optional slot number to access the token. + +secrets.token.module = + Optional PKCS#11 module name to access the token. + +secrets.token.pin = + Optional PIN required to access the key on the token. If none is provided + the user is prompted during an interactive --load-creds call. + pools { # } Section defining named pools.