diff --git a/docs/provider-pkcs11.7 b/docs/provider-pkcs11.7 index 0cbd1b56..27cb173b 100644 --- a/docs/provider-pkcs11.7 +++ b/docs/provider-pkcs11.7 @@ -170,17 +170,25 @@ immediately at application startup) .PP Workarounds that may be needed to deal with some tokens and cannot be autodetcted yet are not appropriate defaults. +.SS no-deinit .PP -The only quirk currently implemented is \[lq]no-deinit\[rq] It prevent -de-initing when OpenSSL winds down the provider. +It prevents de-initing when OpenSSL winds down the provider. NOTE this option may leak memory and may cause some modules to misbehave if the application intentionally unloads and reloads them. +.SS no-operation-state +.PP +OpenSSL by default assumes contexts with operations in flight can be +easily duplicated. +That is only possible if the tokens support getting and setting the +operation state. +If the quirk is enabled the context duplication is not performed. .PP Default: none .PP Example: .PP -\f[C]pkcs11-module-quirks = no-deinit\f[R] (Disables deinitialization) +\f[C]pkcs11-module-quirks = no-deinit no-operation-state\f[R] (Disables +deinitialization) .SH ENVIRONMENT VARIABLES .PP Environment variables recognized by the provider diff --git a/docs/provider-pkcs11.7.md b/docs/provider-pkcs11.7.md index 072e9577..6a1d1703 100644 --- a/docs/provider-pkcs11.7.md +++ b/docs/provider-pkcs11.7.md @@ -178,16 +178,22 @@ Example: Workarounds that may be needed to deal with some tokens and cannot be autodetcted yet are not appropriate defaults. -The only quirk currently implemented is "no-deinit" -It prevent de-initing when OpenSSL winds down the provider. +### no-deinit +It prevents de-initing when OpenSSL winds down the provider. NOTE this option may leak memory and may cause some modules to misbehave if the application intentionally unloads and reloads them. +### no-operation-state +OpenSSL by default assumes contexts with operations in flight can be +easily duplicated. That is only possible if the tokens support getting +and setting the operation state. If the quirk is enabled the context +duplication is not performed. + Default: none Example: -```pkcs11-module-quirks = no-deinit``` +```pkcs11-module-quirks = no-deinit no-operation-state``` (Disables deinitialization) diff --git a/src/digests.c b/src/digests.c index 1810e532..17ffd5de 100644 --- a/src/digests.c +++ b/src/digests.c @@ -191,7 +191,12 @@ static void *p11prov_digest_dupctx(void *ctx) dctx->session = NULL; /* NOTE: most tokens will probably return errors trying to do this on digest - * sessions */ + * sessions. If the configuration indicates that GetOperationState will fail + * we don't even try to duplicate the context. */ + + if (p11prov_ctx_no_operation_state(dctx->provctx)) { + goto done; + } ret = p11prov_GetOperationState(dctx->provctx, sess, NULL_PTR, &state_len); if (ret != CKR_OK) { diff --git a/src/provider.c b/src/provider.c index f4c33107..4519dd31 100644 --- a/src/provider.c +++ b/src/provider.c @@ -35,6 +35,7 @@ struct p11prov_ctx { /* cfg quirks */ bool no_deinit; bool no_allowed_mechanisms; + bool no_operation_state; /* module handles and data */ P11PROV_MODULE *module; @@ -609,6 +610,11 @@ int p11prov_ctx_cache_sessions(P11PROV_CTX *ctx) return ctx->cache_sessions; } +bool p11prov_ctx_no_operation_state(P11PROV_CTX *ctx) +{ + return ctx->no_operation_state; +} + static void p11prov_teardown(void *ctx) { p11prov_ctx_free((P11PROV_CTX *)ctx); @@ -1456,6 +1462,8 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, ctx->no_deinit = true; } else if (strncmp(str, "no-allowed-mechanisms", toklen) == 0) { ctx->no_allowed_mechanisms = true; + } else if (strncmp(str, "no-operation-state", toklen) == 0) { + ctx->no_operation_state = true; } len -= toklen; if (sep) { diff --git a/src/provider.h b/src/provider.h index ad43051c..92560b0b 100644 --- a/src/provider.h +++ b/src/provider.h @@ -115,6 +115,8 @@ enum p11prov_cache_keys { int p11prov_ctx_cache_keys(P11PROV_CTX *ctx); int p11prov_ctx_cache_sessions(P11PROV_CTX *ctx); +bool p11prov_ctx_no_operation_state(P11PROV_CTX *ctx); + #include "debug.h" /* Errors */ diff --git a/src/signature.c b/src/signature.c index 599b7c44..7bfc72e3 100644 --- a/src/signature.c +++ b/src/signature.c @@ -141,6 +141,14 @@ static void *p11prov_sig_dupctx(void *ctx) newctx->session = sigctx->session; sigctx->session = NULL; + /* NOTE: most tokens will probably return errors trying to do this on sign + * sessions. If the configuration indicates that GetOperationState will fail + * we don't even try to duplicate the context. */ + + if (p11prov_ctx_no_operation_state(sigctx->provctx)) { + goto done; + } + if (slotid != CK_UNAVAILABLE_INFORMATION && handle != CK_INVALID_HANDLE) { CK_SESSION_HANDLE newsess = p11prov_session_handle(newctx->session); CK_SESSION_HANDLE sess = CK_INVALID_HANDLE;