Skip to content

Commit

Permalink
Do not cache operations when provider status is uninitialized
Browse files Browse the repository at this point in the history
OpenSSL calls p11prov_query_operation() to query which operations the provider
supports. With the 'no_cache' function argument, the provider can tell OpenSSL
if it is OK to cache the query results or not.

As soon as the PKCS#11 provider has fully initialized, it is OK to cache
the operations, since they won't change during the lifetime of the provider.
However, when the provider has not yet fully initialized, only the KEYMGMT,
DECODER, and STORE operations are fully set up (they are static), but the
other operations have not been set up, and may change when the operations
are eventually initialized. Thus, these operations can not be cached as long
as the provider status is still in 'uninitialized' state.

Operations that the provider does not support at all can always be cached.

Allowing to cache operations that have not been set up may cause various
errors with applications that fetch algorithms before the PKCS#11 provider
is fully initialized. Unless 'pkcs11-module-load-behavior = early' is set,
the provider will only initialize the operations when a PKCS#11 operation is
used the first time, i.e. when a key is generated with the provider, or a
PKCS#11 key or certificate is loaded through the store or via URI-PEM.

When an operation has been queried and is cached before the provider was
fully initialized, then it can happen that OpenSSL remembers that the provider
would not support that algorithm, and will not query the provider again. So
even though that algorithm would be supported by the provider (after full
initialization), OpenSSL would never query the provider again for that
algorithm, but only use the cached information. This can lead to various
failures of the application, e.g. after loading a PKCS#11 key via URI or
URI-PEM, an operation using that key fails, because it won't find the operation
with that key (e.g. SIGNATURE) being supported by the PKCS#11 provider.

Signed-off-by: Ingo Franzki <[email protected]>
  • Loading branch information
ifranzki committed Apr 10, 2024
1 parent 1c90089 commit 83140a7
Showing 1 changed file with 11 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,29 +1158,39 @@ static const OSSL_ALGORITHM *
p11prov_query_operation(void *provctx, int operation_id, int *no_cache)
{
P11PROV_CTX *ctx = (P11PROV_CTX *)provctx;
*no_cache = 0;
switch (operation_id) {
case OSSL_OP_DIGEST:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_digest;
case OSSL_OP_KDF:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_kdf;
case OSSL_OP_RAND:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_random;
case OSSL_OP_KEYMGMT:
*no_cache = 0;
return p11prov_keymgmt;
case OSSL_OP_KEYEXCH:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_exchange;
case OSSL_OP_SIGNATURE:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_signature;
case OSSL_OP_ASYM_CIPHER:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_asym_cipher;
case OSSL_OP_ENCODER:
*no_cache = ctx->status == P11PROV_UNINITIALIZED ? 1 : 0;
return ctx->op_encoder;
case OSSL_OP_DECODER:
*no_cache = 0;
return p11prov_decoders;
case OSSL_OP_STORE:
*no_cache = 0;
return p11prov_store;
}
*no_cache = 0;
return NULL;
}

Expand Down

0 comments on commit 83140a7

Please sign in to comment.