This commit is contained in:
Łukasz Przybylik 2026-04-12 11:37:19 +02:00 committed by GitHub
commit fe1bf5812b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 122 additions and 16 deletions

View file

@ -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.

View file

@ -762,7 +762,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(

View file

@ -688,6 +688,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"
@ -4263,6 +4264,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.");
@ -9187,6 +9196,18 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file,
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])
{

View file

@ -630,6 +630,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

View file

@ -39,6 +39,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)
{
@ -166,6 +175,44 @@ _pkcs11_openvpn_log(void *const global_data, unsigned flags, const char *const s
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(void *const global_data, void *const user_data,
const pkcs11h_token_id_t token, const unsigned retry)
@ -200,11 +247,15 @@ _pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
const pkcs11h_token_id_t token, const unsigned retry, char *const pin,
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;
@ -212,19 +263,25 @@ _pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
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, NULL, prompt,
GET_USER_PASS_MANAGEMENT | GET_USER_PASS_PASSWORD_ONLY
| GET_USER_PASS_NOFATAL))
if (
!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
)
)
{
return false;
}
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)
{
@ -238,12 +295,26 @@ _pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
}
bool
pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
pkcs11_initialize(const bool protected_auth,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 (!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,
@ -271,13 +342,13 @@ pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
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;

View file

@ -27,7 +27,8 @@
#include "ssl_common.h"
bool pkcs11_initialize(const bool fProtectedAuthentication, const int nPINCachePeriod);
bool pkcs11_initialize(const bool fProtectedAuthentication, const int nPINCachePeriod,
const char *pin_file);
void pkcs11_terminate(void);

View file

@ -320,7 +320,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, 60); /* protected auth enabled, pin-cache = 60s */
pkcs11_initialize(true, 60, NULL); /* protected auth enabled, pin-cache = 60s, pin_file = NULL */
pkcs11_addProvider(SOFTHSM2_MODULE_PATH, false, 0, false);
return 0;
}