Skip to content

Commit fb3cd8a

Browse files
committed
Add pkcs11-module-default-slot-id cfg for default slot ID
There are use cases when one wants to select the default slot id (especially when the first slot ID is not convenient for this purpose) which is used for example for storing public keys. As part of this change, the test framework was extended to allow testing of multi slot scenarios. Signed-off-by: Jakub Zelenka <jakub.openssl@gmail.com>
1 parent 103e126 commit fb3cd8a

15 files changed

Lines changed: 267 additions & 27 deletions

docs/provider-pkcs11.7.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,23 @@ Example:
242242

243243
```pkcs11-module-assume-fips = true```
244244

245+
## pkcs11-module-default-slot-id
246+
247+
The default slot ID for new objects.
248+
249+
The default slot is used for any objects that do not have an explicitly
250+
selected slot. Such objects include, for example, public keys.
251+
252+
This option is useful when multiple slots with different PINs are used. In such
253+
cases, it allows you to ensure that pkcs11-module-token-pin points to the
254+
expected slot.
255+
256+
If no value is specified, the first listed slot is used.
257+
258+
Default: none
259+
260+
```pkcs11-module-default-slot-id = 12345```
261+
245262

246263
ENVIRONMENT VARIABLES
247264
=====================

src/provider.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct p11prov_ctx {
3333
int cache_sessions;
3434
bool encode_pkey_as_pk11_uri;
3535
bool assume_fips;
36+
CK_SLOT_ID default_slotid;
3637
/* TODO: ui_method */
3738
/* TODO: fork id */
3839

@@ -463,6 +464,11 @@ P11PROV_INTERFACE *p11prov_ctx_get_interface(P11PROV_CTX *ctx)
463464
return p11prov_module_get_interface(ctx->module);
464465
}
465466

467+
CK_SLOT_ID p11prov_ctx_get_default_slotid(P11PROV_CTX *ctx)
468+
{
469+
return ctx->default_slotid;
470+
}
471+
466472
P11PROV_SLOTS_CTX *p11prov_ctx_get_slots(P11PROV_CTX *ctx)
467473
{
468474
return ctx->slots;
@@ -1778,6 +1784,7 @@ enum p11prov_cfg_enum {
17781784
P11PROV_CFG_ENCODE_PROVIDER_URI_TO_PEM,
17791785
P11PROV_CFG_BLOCK_OPS,
17801786
P11PROV_CFG_ASSUME_FIPS,
1787+
P11PROV_CFG_DEFAULT_SLOT_ID,
17811788
P11PROV_CFG_SIZE,
17821789
};
17831790

@@ -1797,6 +1804,7 @@ static struct p11prov_cfg_names {
17971804
{ "pkcs11-module-encode-provider-uri-to-pem" },
17981805
{ "pkcs11-module-block-operations" },
17991806
{ "pkcs11-module-assume-fips" },
1807+
{ "pkcs11-module-default-slot-id" },
18001808
};
18011809

18021810
int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in,
@@ -2090,6 +2098,24 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in,
20902098
return RET_OSSL_ERR;
20912099
}
20922100

2101+
if (cfg[P11PROV_CFG_DEFAULT_SLOT_ID] != NULL) {
2102+
char *end = NULL;
2103+
errno = 0;
2104+
ctx->default_slotid =
2105+
strtoul(cfg[P11PROV_CFG_DEFAULT_SLOT_ID], &end, 0);
2106+
if (errno != 0 || *end != '\0') {
2107+
P11PROV_raise(ctx, CKR_GENERAL_ERROR, "Invalid value for %s: (%s)",
2108+
p11prov_cfg_names[P11PROV_CFG_DEFAULT_SLOT_ID].name,
2109+
cfg[P11PROV_CFG_DEFAULT_SLOT_ID]);
2110+
p11prov_ctx_free(ctx);
2111+
return RET_OSSL_ERR;
2112+
}
2113+
P11PROV_debug("Default slot ID: %lu", ctx->default_slotid);
2114+
} else {
2115+
ctx->default_slotid = CK_UNAVAILABLE_INFORMATION;
2116+
P11PROV_debug("Default slot ID: None");
2117+
}
2118+
20932119
/* PAY ATTENTION: do this as the last thing */
20942120
if (cfg[P11PROV_CFG_LOAD_BEHAVIOR] != NULL
20952121
&& strcmp(cfg[P11PROV_CFG_LOAD_BEHAVIOR], "early") == 0) {

src/provider.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ P11PROV_INTERFACE *p11prov_ctx_get_interface(P11PROV_CTX *ctx);
268268
CK_UTF8CHAR_PTR p11prov_ctx_pin(P11PROV_CTX *ctx);
269269
OSSL_LIB_CTX *p11prov_ctx_get_libctx(P11PROV_CTX *ctx);
270270
CK_RV p11prov_ctx_status(P11PROV_CTX *ctx);
271+
CK_SLOT_ID p11prov_ctx_get_default_slotid(P11PROV_CTX *ctx);
271272
P11PROV_SLOTS_CTX *p11prov_ctx_get_slots(P11PROV_CTX *ctx);
272273
void p11prov_ctx_set_slots(P11PROV_CTX *ctx, P11PROV_SLOTS_CTX *slots);
273274
CK_RV p11prov_ctx_get_quirk(P11PROV_CTX *ctx, CK_SLOT_ID id, const char *name,

src/slot.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ CK_RV p11prov_init_slots(P11PROV_CTX *ctx, P11PROV_SLOTS_CTX **slots)
173173
}
174174

175175
sctx->default_slot = CK_UNAVAILABLE_INFORMATION;
176+
CK_SLOT_ID prov_default_slotid =
177+
p11prov_ctx_get_default_slotid(sctx->provctx);
176178

177179
for (size_t i = 0; i < num; i++) {
178180
P11PROV_SLOT *slot;
@@ -238,6 +240,8 @@ CK_RV p11prov_init_slots(P11PROV_CTX *ctx, P11PROV_SLOTS_CTX **slots)
238240
* softoken has a slot that can't be used to store session keys)
239241
* and the following query excludes it */
240242
if ((sctx->default_slot == CK_UNAVAILABLE_INFORMATION)
243+
&& (prov_default_slotid == CK_UNAVAILABLE_INFORMATION
244+
|| prov_default_slotid == slot->id)
241245
&& (slot->token.flags & CKF_LOGIN_REQUIRED)
242246
&& (slot->token.flags & CKF_TOKEN_INITIALIZED)
243247
&& (!(slot->token.flags & CKF_USER_PIN_LOCKED))) {

tests/helpers.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ ptool() {
117117
if [ -n "$P11DEFLOGIN" ]; then
118118
CMDOPTS+=("${P11DEFLOGIN[@]}")
119119
fi
120+
if [ -n "$SLOTID" ]; then
121+
CMDOPTS+=("--slot=${SLOTID}")
122+
fi
120123
CMDOPTS+=("$@")
121124
# when running sanitizer tests libasan is linked via pkcs11-provider into
122125
# openssl and pkcs11-tool is linked to libcrypto, so we need to break the

tests/kryoptic-init.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ find_kryoptic \
2626

2727
title LINE "Creating Kryoptic database"
2828

29+
SLOTID=${SLOTID:-0}
30+
2931
# Kryoptic configuration
3032
cat << EOF > "$TOKDIR/kryoptic.conf"
3133
[[slots]]
32-
slot = 0
34+
slot = $SLOTID
3335
dbtype = "sqlite"
3436
dbargs = "$TOKDIR/kryoptic.sql"
3537
#mechanisms
@@ -40,10 +42,11 @@ export TOKENLABEL="${TOKENLABEL:-Kryoptic Token}"
4042
export TOKENLABELURI="${TOKENLABELURI:-Kryoptic%20Token}"
4143

4244
# init token
43-
ptool --init-token --label "${TOKENLABEL}" --so-pin "${PINVALUE}" 2>&1
45+
ptool --init-token --slot "${SLOTID}" --label "${TOKENLABEL}" \
46+
--so-pin "${PINVALUE}" 2>&1
4447
# set user pin
45-
ptool --so-pin "${PINVALUE}" --login --login-type so --init-pin \
46-
--pin "${PINVALUE}" 2>&1
48+
ptool --so-pin "${PINVALUE}" --slot "${SLOTID}" --login --login-type so \
49+
--init-pin --pin "${PINVALUE}" 2>&1
4750

4851
export TOKENCONFIGVARS="export KRYOPTIC_CONF=$TOKDIR/kryoptic.conf"
4952

tests/kryoptic.multislot-init.sh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/bin/bash -ex
2+
# Copyright (C) 2024 Jakub Zelenka <jakub.openssl@gmail.com>
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
export SLOTID=42
7+
export SLOTID2=52
8+
export TOKEN2LABEL="${TOKENLABEL:-Kryoptic Token 2}"
9+
export TOKEN2LABELURI="${TOKENLABELURI:-Kryoptic%20Token%202}"
10+
export PIN2VALUE=11111111
11+
12+
export KRYOPTIC_CONF="${TMPPDIR}/kryoptic.conf"
13+
cat >"${KRYOPTIC_CONF}" <<_EOF
14+
[[slots]]
15+
slot = $SLOTID
16+
dbtype = "sqlite"
17+
dbargs = "$TOKDIR/kryoptic.sql"
18+
#mechanisms
19+
[[slots]]
20+
slot = $SLOTID2
21+
dbtype = "sqlite"
22+
dbargs = "${TOKDIR}/kryoptic2.sql"
23+
description = "Kryoptic Token 2"
24+
_EOF
25+
26+
# this overrides what we define in the generic init
27+
export TOKENLABEL="Kryoptic Soft Token"
28+
export TOKENLABELURI="Kryoptic%20Soft%20Token"
29+
30+
# the rest is the same
31+
source "${TESTSSRCDIR}/kryoptic-init.sh"
32+
33+
# init token 2
34+
pkcs11-tool --module "${P11LIB}" --init-token --slot "${SLOTID2}" \
35+
--label "${TOKEN2LABEL}" --so-pin "${PIN2VALUE}" 2>&1
36+
# set user pin 2
37+
pkcs11-tool --module "${P11LIB}" --so-pin "${PIN2VALUE}" --slot "${SLOTID2}" \
38+
--login --login-type so --init-pin --pin "${PIN2VALUE}" 2>&1
39+
40+
export TOKENCONFIGVARS="export KRYOPTIC_CONF=${TMPPDIR}/kryoptic.conf"
41+
export TESTPORT="29000"
42+
43+
# generate RSA key
44+
KEYID='0201'
45+
URIKEYID="%02%01"
46+
47+
pkcs11-tool --module "${P11LIB}" --slot "${SLOTID2}" --pin "${PIN2VALUE}" \
48+
--keypairgen --key-type="RSA:2048" --id="$KEYID" \
49+
--label="testKey" 2>&1
50+
51+
export BASEURI2WITHPINVALUE="pkcs11:id=${URIKEYID}?pin-value=${PINVALUE}"
52+
export BASEURI2="pkcs11:id=${URIKEYID}"
53+
export PUBURI2="pkcs11:type=public;id=${URIKEYID}"
54+
export PRIURI2="pkcs11:type=private;id=${URIKEYID}"
55+
56+
title LINE "RSA PKCS11 URIS"
57+
echo "${BASEURI2WITHPINVALUE}"
58+
echo "${BASEURI2}"
59+
echo "${PUBURI2}"
60+
echo "${PRIURI2}"
61+
echo ""
62+
63+
# While this works with the default DB, the NSS DB does not support this
64+
# attribute
65+
export SUPPORT_ALLOWED_MECHANISMS=0

tests/kryoptic.nss-init.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
# SPDX-License-Identifier: Apache-2.0
44
#
55

6+
export SLOTID=42
7+
export SLOTSCOUNT=1
8+
69
export KRYOPTIC_CONF="${TMPPDIR}/kryoptic.conf"
710
cat >"${KRYOPTIC_CONF}" <<_EOF
811
[[slots]]
9-
slot = 42
12+
slot = ${SLOTID}
1013
dbtype = "nssdb"
1114
dbargs = "configDir='${TOKDIR}' flags='passwordRequired'"
1215
description = "Kryoptic Soft Token"

tests/meson.build

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ test_programs = {
104104
'treadkeys': ['treadkeys.c'],
105105
'tcmpkeys': ['tcmpkeys.c', 'util.c'],
106106
'tfork': ['tfork.c', 'util.c'],
107+
'tstorepubkey': ['tstorepubkey.c', 'util.c'],
107108
'tpkey': ['tpkey.c', 'util.c'],
108109
'pincache': ['pincache.c'],
109110
'ccerts': ['ccerts.c', 'util.c'],
@@ -122,7 +123,9 @@ foreach t, sources : test_programs
122123
endforeach
123124

124125
setup_script=find_program('setup.sh')
125-
all_suites=['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']
126+
multi_suites=['kryoptic.multislot']
127+
single_suites=['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']
128+
all_suites=single_suites + multi_suites
126129
foreach suite : all_suites
127130
test(
128131
'setup',
@@ -136,39 +139,40 @@ foreach suite : all_suites
136139
endforeach
137140

138141
tests = {
139-
'basic': {'suites': all_suites},
142+
'basic': {'suites': single_suites},
140143
'mlkem': {'suites': ['kryoptic']},
141144
'mldsa': {'suites': ['kryoptic']},
142-
'pubkey': {'suites': all_suites},
143-
'certs': {'suites': all_suites},
144-
'ecc': {'suites': all_suites},
145+
'pubkey': {'suites': single_suites},
146+
'certs': {'suites': single_suites},
147+
'ecc': {'suites': single_suites},
145148
'edwards': {'suites': ['softhsm', 'kryoptic', 'kryoptic.nss']},
146-
'ecdh': {'suites': all_suites},
147-
'democa': {'suites': all_suites, 'is_parallel': false},
148-
'digest': {'suites': all_suites},
149-
'fork': {'suites': all_suites},
149+
'ecdh': {'suites': single_suites},
150+
'democa': {'suites': single_suites, 'is_parallel': false},
151+
'digest': {'suites': single_suites},
152+
'fork': {'suites': single_suites},
150153
'oaepsha2': {'suites': ['softokn', 'kryoptic', 'kryoptic.nss']},
151154
'hkdf': {'suites': ['softokn', 'kryoptic', 'kryoptic.nss']},
152155
'imported' : {'suites': ['softokn', 'kryoptic', 'kryoptic.nss']},
153-
'pem_encoder': {'suites': all_suites},
154-
'rsa': {'suites': all_suites},
155-
'rsapss': {'suites': all_suites},
156+
'pem_encoder': {'suites': single_suites},
157+
'rsa': {'suites': single_suites},
158+
'rsapss': {'suites': single_suites},
156159
'rsapssam': {'suites': ['softhsm', 'kryoptic']},
157-
'genkey': {'suites': all_suites},
158-
'pkey': {'suites': all_suites},
160+
'genkey': {'suites': single_suites},
161+
'pkey': {'suites': single_suites},
159162
'pkey_provider': {'suites': ['kryoptic', 'kryoptic.nss', 'softokn']},
160-
'session': {'suites': all_suites},
163+
'session': {'suites': single_suites},
161164
'skey': {'suites': ['softokn', 'kryoptic', 'kryoptic.nss'], 'timeout': 90},
162-
'rand': {'suites': all_suites},
163-
'readkeys': {'suites': all_suites},
164-
'tls': {'suites': all_suites, 'is_parallel': false, 'timeout': 60},
165-
'tlsfuzzer': {'suites': all_suites, 'timeout': 90},
166-
'uri': {'suites': all_suites, 'timeout': 90},
165+
'rand': {'suites': single_suites},
166+
'readkeys': {'suites': single_suites},
167+
'tls': {'suites': single_suites, 'is_parallel': false, 'timeout': 60},
168+
'tlsfuzzer': {'suites': single_suites, 'timeout': 90},
169+
'uri': {'suites': single_suites, 'timeout': 90},
167170
'ecxc': {'suites': ['softhsm', 'kryoptic', 'kryoptic.nss']},
168171
'cms': {'suites': ['softokn', 'kryoptic', 'kryoptic.nss']},
169172
'pinlock': {'suites': ['kryoptic']},
170173
'aead': {'suites': ['softokn', 'kryoptic', 'kryoptic.nss']},
171174
'op_state': {'suites': all_suites},
175+
'defaultslot': {'suites': ['kryoptic.multislot']},
172176
}
173177

174178
test_wrapper = find_program('test-wrapper')

tests/openssl.cnf.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ activate = 1
2323
[pkcs11_sect]
2424
module = @libtoollibs@/pkcs11@SHARED_EXT@
2525
pkcs11-module-token-pin = file:@PINFILE@
26+
#pkcs11-module-default-slot-id
2627
##TOKENOPTIONS
2728
#pkcs11-module-encode-provider-uri-to-pem
2829
#pkcs11-module-allow-export

0 commit comments

Comments
 (0)