Skip to content

Commit 80ce634

Browse files
committed
added pkcs11-pin feature
1 parent 7ac5f89 commit 80ce634

7 files changed

Lines changed: 158 additions & 16 deletions

File tree

doc/man-sections/pkcs11-options.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,15 @@ PKCS#11 / SmartCard options
8383

8484
``--verb`` option can be used BEFORE this option to produce debugging
8585
information.
86+
87+
--pkcs11-pin pin
88+
Specify the file with the PIN for the PKCS#11 token.
89+
90+
Valid syntax:
91+
::
92+
93+
pkcs11-pin file.txt
94+
95+
If the PIN is specified from file, the file should contain only the PIN,
96+
without any additional characters.
97+
When ``--pkcs11-pin`` is not specified, the user will be prompted to enter the PIN.

src/openvpn/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ context_init_1(struct context *c)
762762
if (c->first_time)
763763
{
764764
int i;
765-
pkcs11_initialize(true, c->options.pkcs11_pin_cache_period);
765+
pkcs11_initialize(true, c->options.pkcs11_pin_cache_period, c->options.pkcs11_pin_file);
766766
for (i = 0; i < MAX_PARMS && c->options.pkcs11_providers[i] != NULL; i++)
767767
{
768768
pkcs11_addProvider(

src/openvpn/options.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ static const char usage_message[] =
687687
" cache until token is removed.\n"
688688
"--pkcs11-id-management : Acquire identity from management interface.\n"
689689
"--pkcs11-id serialized-id 'id' : Identity to use, get using standalone --show-pkcs11-ids\n"
690+
"--pkcs11-pin file : File containing the PIN for the PKCS#11 token.\n"
690691
#endif /* ENABLE_PKCS11 */
691692
"\n"
692693
"SSL Library information:\n"
@@ -4256,6 +4257,14 @@ options_postprocess_filechecks(struct options *options)
42564257
errs |= check_file_access_chroot(options->chroot_dir, CHKACC_FILE, options->tmp_dir,
42574258
R_OK | W_OK | X_OK, "Temporary directory (--tmp-dir)");
42584259

4260+
#ifdef ENABLE_PKCS11
4261+
if (options->pkcs11_pin_file)
4262+
{
4263+
errs |= check_file_access(CHKACC_FILE|CHKACC_ACPTSTDIN|CHKACC_PRIVATE,
4264+
options->pkcs11_pin_file, R_OK, "--pkcs11-pin");
4265+
}
4266+
#endif
4267+
42594268
if (errs)
42604269
{
42614270
msg(M_USAGE, "Please correct these errors.");
@@ -9174,6 +9183,18 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file,
91749183
VERIFY_PERMISSION(OPT_P_GENERAL);
91759184
options->pkcs11_id_management = true;
91769185
}
9186+
else if (streq(p[0], "pkcs11-pin") && p[1] && !p[2])
9187+
{
9188+
VERIFY_PERMISSION(OPT_P_GENERAL);
9189+
if (p[1])
9190+
{
9191+
options->pkcs11_pin_file = p[1];
9192+
}
9193+
else
9194+
{
9195+
options->pkcs11_pin_file = NULL;
9196+
}
9197+
}
91779198
#endif /* ifdef ENABLE_PKCS11 */
91789199
else if (streq(p[0], "rmtun") && !p[1])
91799200
{

src/openvpn/options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ struct options
629629
int pkcs11_pin_cache_period;
630630
const char *pkcs11_id;
631631
bool pkcs11_id_management;
632+
const char *pkcs11_pin_file;
632633
#endif
633634

634635
#ifdef ENABLE_CRYPTOAPI

src/openvpn/pkcs11.c

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@
3939
#include "console.h"
4040
#include "pkcs11_backend.h"
4141

42+
43+
struct pkcs11_context {
44+
int nPINCachePeriod;
45+
struct user_pass token_pass;
46+
const char *pin_file;
47+
};
48+
49+
static struct pkcs11_context pkcs11_ctx; /* GLOBAL */
50+
4251
static time_t
4352
__mytime(void)
4453
{
@@ -166,6 +175,80 @@ _pkcs11_openvpn_log(void *const global_data, unsigned flags, const char *const s
166175
msg(_pkcs11_msg_pkcs112openvpn(flags), "%s", Buffer);
167176
}
168177

178+
static
179+
PKCS11H_BOOL
180+
pkcs11_password_setup(
181+
const char *pkcs11_pin_file,
182+
struct user_pass *token_pass
183+
)
184+
{
185+
if (!token_pass)
186+
{
187+
return false;
188+
}
189+
if (pkcs11_pin_file)
190+
{
191+
msg(M_INFO, "pkcs11_password_setup - pkcs11_pin_file='%s'", pkcs11_pin_file);
192+
}
193+
else
194+
{
195+
/* If pin file is not provided, clear the token_pass and continue */
196+
CLEAR(token_pass);
197+
return true;
198+
}
199+
token_pass->defined = false;
200+
token_pass->nocache = true;
201+
202+
if (!strlen(token_pass->password))
203+
{
204+
get_user_pass(
205+
token_pass,
206+
pkcs11_pin_file,
207+
UP_TYPE_PRIVATE_KEY,
208+
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY
209+
);
210+
}
211+
212+
return true;
213+
}
214+
215+
static
216+
PKCS11H_BOOL
217+
pkcs11_password_setup(
218+
const char *pkcs11_pin_file,
219+
struct user_pass *token_pass
220+
)
221+
{
222+
if (!token_pass)
223+
{
224+
return false;
225+
}
226+
if (pkcs11_pin_file)
227+
{
228+
msg(M_INFO, "pkcs11_password_setup - pkcs11_pin_file='%s'", pkcs11_pin_file);
229+
}
230+
else
231+
{
232+
/* If pin file is not provided, clear the token_pass and continue */
233+
CLEAR(token_pass);
234+
return true;
235+
}
236+
token_pass->defined = false;
237+
token_pass->nocache = true;
238+
239+
if (!strlen(token_pass->password))
240+
{
241+
get_user_pass(
242+
token_pass,
243+
pkcs11_pin_file,
244+
UP_TYPE_PRIVATE_KEY,
245+
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY
246+
);
247+
}
248+
249+
return true;
250+
}
251+
169252
static PKCS11H_BOOL
170253
_pkcs11_openvpn_token_prompt(void *const global_data, void *const user_data,
171254
const pkcs11h_token_id_t token, const unsigned retry)
@@ -200,31 +283,41 @@ _pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
200283
const pkcs11h_token_id_t token, const unsigned retry, char *const pin,
201284
const size_t pin_max)
202285
{
203-
struct user_pass token_pass;
204286
char prompt[1024];
205-
CLEAR(token_pass);
287+
struct pkcs11_context *ctx = NULL;
288+
289+
if (!global_data)
290+
{
291+
return false;
292+
}
293+
ctx = (struct pkcs11_context *)global_data;
206294

207-
(void)global_data;
208295
(void)user_data;
209296
(void)retry;
210297

211298
ASSERT(token != NULL);
212299

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

215-
token_pass.defined = false;
216-
token_pass.nocache = true;
302+
ctx->token_pass.defined = false;
303+
ctx->token_pass.nocache = true;
217304

218-
if (!get_user_pass(&token_pass, NULL, prompt,
219-
GET_USER_PASS_MANAGEMENT | GET_USER_PASS_PASSWORD_ONLY
220-
| GET_USER_PASS_NOFATAL))
305+
if (
306+
!strlen(ctx->token_pass.password)
307+
&& !get_user_pass(
308+
&ctx->token_pass,
309+
NULL,
310+
prompt,
311+
GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
312+
)
313+
)
221314
{
222315
return false;
223316
}
224317
else
225318
{
226-
strncpynt(pin, token_pass.password, pin_max);
227-
purge_user_pass(&token_pass, true);
319+
strncpynt(pin, ctx->token_pass.password, pin_max);
320+
purge_user_pass(&ctx->token_pass, true);
228321

229322
if (strlen(pin) == 0)
230323
{
@@ -238,12 +331,26 @@ _pkcs11_openvpn_pin_prompt(void *const global_data, void *const user_data,
238331
}
239332

240333
bool
241-
pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
334+
pkcs11_initialize(const bool protected_auth,const int nPINCachePeriod,
335+
const char *pin_file)
242336
{
243337
CK_RV rv = CKR_FUNCTION_FAILED;
338+
pkcs11_ctx.nPINCachePeriod = nPINCachePeriod;
244339

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

342+
if (!pkcs11_password_setup(pin_file, &pkcs11_ctx.token_pass))
343+
{
344+
msg(M_FATAL, "PKCS#11: Cannot initialize pkcs11 password");
345+
return false;
346+
}
347+
348+
if (!pkcs11_password_setup(pin_file, &pkcs11_ctx.token_pass))
349+
{
350+
msg(M_FATAL, "PKCS#11: Cannot initialize pkcs11 password");
351+
return false;
352+
}
353+
247354
if ((rv = pkcs11h_engine_setSystem(&s_pkcs11h_sys_engine)) != CKR_OK)
248355
{
249356
msg(M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv,
@@ -271,13 +378,13 @@ pkcs11_initialize(const bool protected_auth, const int nPINCachePeriod)
271378
goto cleanup;
272379
}
273380

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

280-
if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK)
387+
if ((rv = pkcs11h_setPINPromptHook(_pkcs11_openvpn_pin_prompt, &pkcs11_ctx)) != CKR_OK)
281388
{
282389
msg(M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage(rv));
283390
goto cleanup;

src/openvpn/pkcs11.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727

2828
#include "ssl_common.h"
2929

30-
bool pkcs11_initialize(const bool fProtectedAuthentication, const int nPINCachePeriod);
30+
bool pkcs11_initialize(const bool fProtectedAuthentication, const int nPINCachePeriod,
31+
const char *pin_file);
3132

3233
void pkcs11_terminate(void);
3334

tests/unit_tests/openvpn/test_pkcs11.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ setup_pkcs11(void **state)
320320
/* set default propq as we do in ssl_openssl.c */
321321
EVP_set_default_properties(tls_libctx, "?provider!=ovpn.xkey");
322322
#endif
323-
pkcs11_initialize(true, 60); /* protected auth enabled, pin-cache = 60s */
323+
pkcs11_initialize(true, 60, NULL); /* protected auth enabled, pin-cache = 60s, pin_file = NULL */
324324
pkcs11_addProvider(SOFTHSM2_MODULE_PATH, false, 0, false);
325325
return 0;
326326
}

0 commit comments

Comments
 (0)