Skip to content

added pkcs11-pin feature #740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/man-sections/pkcs11-options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,15 @@ PKCS#11 / SmartCard options

``--verb`` option can be used BEFORE this option to produce debugging
information.

--pkcs11-pin pin
Specify the file with the PIN for the PKCS#11 token.

Valid syntax:
::

pkcs11-pin file.txt

If the PIN is specified from file, the file should contain only the PIN,
without any additional characters.
When ``--pkcs11-pin`` is not specified, the user will be prompted to enter the PIN.
2 changes: 1 addition & 1 deletion src/openvpn/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ context_init_1(struct context *c)
if (c->first_time)
{
int i;
pkcs11_initialize(true, c->options.pkcs11_pin_cache_period);
pkcs11_initialize(true, c->options.pkcs11_pin_cache_period, c->options.pkcs11_pin_file);
for (i = 0; i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL; i++)
{
pkcs11_addProvider(c->options.pkcs11_providers[i], c->options.pkcs11_protected_authentication[i],
Expand Down
21 changes: 21 additions & 0 deletions src/openvpn/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,7 @@ static const char usage_message[] =
" cache until token is removed.\n"
"--pkcs11-id-management : Acquire identity from management interface.\n"
"--pkcs11-id serialized-id 'id' : Identity to use, get using standalone --show-pkcs11-ids\n"
"--pkcs11-pin file : File containing the PIN for the PKCS#11 token.\n"
#endif /* ENABLE_PKCS11 */
"\n"
"SSL Library information:\n"
Expand Down Expand Up @@ -4153,6 +4154,14 @@ options_postprocess_filechecks(struct options *options)
errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE, options->tmp_dir,
R_OK|W_OK|X_OK, "Temporary directory (--tmp-dir)");

#ifdef ENABLE_PKCS11
if (options->pkcs11_pin_file)
{
errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
options->pkcs11_pin_file, R_OK, "--pkcs11-pin");
}
#endif

if (errs)
{
msg(M_USAGE, "Please correct these errors.");
Expand Down Expand Up @@ -9444,6 +9453,18 @@ add_option(struct options *options,
VERIFY_PERMISSION(OPT_P_GENERAL);
options->pkcs11_id_management = true;
}
else if (streq(p[0], "pkcs11-pin") && p[1] && !p[2])
{
VERIFY_PERMISSION(OPT_P_GENERAL);
if (p[1])
{
options->pkcs11_pin_file = p[1];
}
else
{
options->pkcs11_pin_file = NULL;
}
}
#endif /* ifdef ENABLE_PKCS11 */
else if (streq(p[0], "rmtun") && !p[1])
{
Expand Down
1 change: 1 addition & 0 deletions src/openvpn/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,7 @@ struct options
int pkcs11_pin_cache_period;
const char *pkcs11_id;
bool pkcs11_id_management;
const char *pkcs11_pin_file;
#endif

#ifdef ENABLE_CRYPTOAPI
Expand Down
83 changes: 71 additions & 12 deletions src/openvpn/pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@
#include "console.h"
#include "pkcs11_backend.h"


struct pkcs11_context {
int nPINCachePeriod;
struct user_pass token_pass;
const char *pin_file;
};

static struct pkcs11_context pkcs11_ctx; /* GLOBAL */

static
time_t
__mytime(void)
Expand Down Expand Up @@ -181,6 +190,43 @@ _pkcs11_openvpn_log(
msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer);
}

static
PKCS11H_BOOL
pkcs11_password_setup(
const char *pkcs11_pin_file,
struct user_pass *token_pass
)
{
if (!token_pass)
{
return false;
}
if (pkcs11_pin_file)
{
msg(M_INFO, "pkcs11_password_setup - pkcs11_pin_file='%s'", pkcs11_pin_file);
}
else
{
/* If pin file is not provided, clear the token_pass and continue */
CLEAR(token_pass);
return true;
}
token_pass->defined = false;
token_pass->nocache = true;

if (!strlen(token_pass->password))
{
get_user_pass(
token_pass,
pkcs11_pin_file,
UP_TYPE_PRIVATE_KEY,
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY
);
}

return true;
}

static
PKCS11H_BOOL
_pkcs11_openvpn_token_prompt(
Expand Down Expand Up @@ -236,24 +282,29 @@ _pkcs11_openvpn_pin_prompt(
const size_t pin_max
)
{
struct user_pass token_pass;
char prompt[1024];
CLEAR(token_pass);
struct pkcs11_context *ctx = NULL;

if (!global_data)
{
return false;
}
ctx = (struct pkcs11_context *)global_data;

(void)global_data;
(void)user_data;
(void)retry;

ASSERT(token!=NULL);

snprintf(prompt, sizeof(prompt), "%s token", token->label);

token_pass.defined = false;
token_pass.nocache = true;
ctx->token_pass.defined = false;
ctx->token_pass.nocache = true;

if (
!get_user_pass(
&token_pass,
!strlen(ctx->token_pass.password)
&& !get_user_pass(
&ctx->token_pass,
NULL,
prompt,
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
Expand All @@ -264,8 +315,8 @@ _pkcs11_openvpn_pin_prompt(
}
else
{
strncpynt(pin, token_pass.password, pin_max);
purge_user_pass(&token_pass, true);
strncpynt(pin, ctx->token_pass.password, pin_max);
purge_user_pass(&ctx->token_pass, true);

if (strlen(pin) == 0)
{
Expand All @@ -281,16 +332,24 @@ _pkcs11_openvpn_pin_prompt(
bool
pkcs11_initialize(
const bool protected_auth,
const int nPINCachePeriod
const int nPINCachePeriod,
const char *pin_file
)
{
CK_RV rv = CKR_FUNCTION_FAILED;
pkcs11_ctx.nPINCachePeriod = nPINCachePeriod;

dmsg(
D_PKCS11_DEBUG,
"PKCS#11: pkcs11_initialize - entered"
);

if (!pkcs11_password_setup(pin_file, &pkcs11_ctx.token_pass))
{
msg(M_FATAL, "PKCS#11: Cannot initialize pkcs11 password");
return false;
}

if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
{
msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage(rv));
Expand All @@ -317,13 +376,13 @@ pkcs11_initialize(
goto cleanup;
}

if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK)
if ((rv = pkcs11h_setTokenPromptHook(_pkcs11_openvpn_token_prompt, &pkcs11_ctx)) != CKR_OK)
{
msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
goto cleanup;
}

if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, &pkcs11_ctx)) != CKR_OK)
{
msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
goto cleanup;
Expand Down
3 changes: 2 additions & 1 deletion src/openvpn/pkcs11.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
bool
pkcs11_initialize(
const bool fProtectedAuthentication,
const int nPINCachePeriod
const int nPINCachePeriod,
const char *pin_file
);

void
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/openvpn/test_pkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ setup_pkcs11(void **state)
/* set default propq as we do in ssl_openssl.c */
EVP_set_default_properties(tls_libctx, "?provider!=ovpn.xkey");
#endif
pkcs11_initialize(true, 0); /* protected auth enabled, pin-cache = 0 */
pkcs11_initialize(true, 0, NULL); /* protected auth enabled, pin-cache = 0, pin_file = NULL */
pkcs11_addProvider(SOFTHSM2_MODULE_PATH, false, 0, false);
return 0;
}
Expand Down