Add support for Yubico tokens - #87
Conversation
keldonin
commented
Jul 8, 2026
- Updated wrappedkey_lexer.l to include new key types for Yubico AES wrapping (CKK_YUBICO_AES128_CCM_WRAP, CKK_YUBICO_AES192_CCM_WRAP, CKK_YUBICO_AES256_CCM_WRAP) with conditional compilation based on HAVE_YUBICO.
- Modified wrappedkey_lexer.h to adjust line numbers for lexer definitions.
- Refactored multiple source files (p11cat.c, p11cp.c, p11kcv.c, p11ls.c, p11more.c, p11mv.c, p11od.c, p11rm.c) to save the value of optind before opening the PKCS#11 library, ensuring correct argument parsing when using Yubico tokens.
- Added a new script (with_yubico) for Yubico-specific configurations and usage, including handling of the Yubihsm library and configuration file paths.
There was a problem hiding this comment.
Pull request overview
This PR adds Yubico YubiHSM2-oriented support to pkcs11-tools, including recognition of Yubico vendor key types and operational fixes needed for some vendor PKCS#11 stacks (notably around argument parsing and object mutation workflows).
Changes:
- Added Yubico vendor extensions (new
CKK_YUBICO_AES{128,192,256}_CCM_WRAPkey types, wrapper script, headers, and documentation). - Hardened CLI tools’ argument handling by preserving
optindacross PKCS#11 library initialization for tokens that modify it. - Refactored mutation commands (cp/mv/rm/setattr) to prefetch matching object handles before mutating, with a new
--with-prefetch-max-objectsconfigure option; plus fixes to table generation sort order for bsearch() consistency.
Reviewed changes
Copilot reviewed 31 out of 33 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
with_yubico |
New YubiHSM2 wrapper script and default environment setup. |
with_pkcs11_common |
Adds a yubico vendor stanza to the common wrapper logic. |
src/p11cat.c |
Preserves optind before loading PKCS#11 library. |
src/p11cp.c |
Preserves optind before loading PKCS#11 library. |
src/p11kcv.c |
Preserves optind before loading PKCS#11 library. |
src/p11ls.c |
Preserves optind before loading PKCS#11 library. |
src/p11more.c |
Preserves optind before loading PKCS#11 library. |
src/p11mv.c |
Preserves optind before loading PKCS#11 library. |
src/p11od.c |
Preserves optind before loading PKCS#11 library. |
src/p11rm.c |
Preserves optind before loading PKCS#11 library. |
README.md |
Points to consolidated vendor limitations section in the manual. |
Makefile.am |
Installs/distributes the new with_yubico wrapper. |
dist/solaris/pkgproto.in |
Adds with_yubico to Solaris packaging manifest. |
configure.ac |
Adds --with-prefetch-max-objects and Yubico feature detection/flagging. |
CHANGELOG.md |
Documents Yubico support and related behavioral changes/fixes. |
docs/MANUAL.md |
Documents Yubico key types and adds vendor-specific limitations section. |
include/cryptoki/yubico.h |
Introduces Yubico vendor key/mechanism numeric definitions. |
include/cryptoki/pkcs11extra.h |
Conditionally includes Yubico vendor header when enabled. |
lib/wrappedkey_lexer.l |
Adds Yubico key-type tokens for wrapped-key parsing. |
lib/wrappedkey_lexer.h |
Updates generated header line markers for lexer. |
lib/wrappedkey_lexer.c |
Updates generated lexer implementation (new rules/tables). |
lib/attribctx_lexer.l |
Adds Yubico key-type tokens for attribute-context parsing. |
lib/attribctx_lexer.h |
Updates generated header line markers for lexer. |
lib/pkcs11_ls.c |
Displays Yubico CCM-wrap AES keys with distinct p11ls formatting. |
lib/pkcs11_od.c |
Decodes Yubico key type constants in object dump output. |
lib/pkcs11_x509.c |
Extends EC-style CKA_ID derivation behavior to Ed25519/Ed448; adjusts cert template. |
lib/pkcs11_cp.c |
Prefetches handles before copy operations; enforces a configurable max. |
lib/pkcs11_mv.c |
Prefetches handles before move operations; enforces a configurable max. |
lib/pkcs11_rm.c |
Prefetches handles before delete operations; enforces a configurable max. |
lib/pkcs11_chattr.c |
Prefetches handles before setattr operations; enforces a configurable max. |
lib/gen_mechinfo_h.pl |
Fixes table uniqueness/sort to be numeric and bsearch()-compatible. |
lib/gen_attrinfo_h.pl |
Fixes attribute-name sort to be case-insensitive and bsearch()-compatible. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@keldonin found two possible issues. Happy to patch for you, let me know. |
9f0c208 to
3f4b08d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 36 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
lib/wrappedkey_lexer.l:133
- The lexer unconditionally references CKK_YUBICO_* constants. When configuring with
--without-yubico,HAVE_YUBICOis not defined soinclude/cryptoki/yubico.his not included (via cryptoki.h -> pkcs11extra.h), and these identifiers become undefined, breaking the build. Guard the Yubico key-type rules with#if defined(HAVE_YUBICO)(or otherwise ensure the constants are available) and regenerate the checked-in lexer outputs.
CKK_YUBICO_AES128_CCM_WRAP { yylval.val_key = CKK_YUBICO_AES128_CCM_WRAP; return KEYTYPE; }
CKK_YUBICO_AES192_CCM_WRAP { yylval.val_key = CKK_YUBICO_AES192_CCM_WRAP; return KEYTYPE; }
CKK_YUBICO_AES256_CCM_WRAP { yylval.val_key = CKK_YUBICO_AES256_CCM_WRAP; return KEYTYPE; }
lib/attribctx_lexer.l:109
- Like wrappedkey_lexer.l, this lexer unconditionally references CKK_YUBICO_* constants. With
--without-yubico(no HAVE_YUBICO), those constants are not defined (yubico.h isn’t included), so the build will fail. Wrap these Yubico key-type rules in#if defined(HAVE_YUBICO)and regenerate the generated lexer sources.
CKK_YUBICO_AES128_CCM_WRAP|YUBICO_AES128_CCM_WRAP { cllval.val_key = CKK_YUBICO_AES128_CCM_WRAP; return KEYTYPE; }
CKK_YUBICO_AES192_CCM_WRAP|YUBICO_AES192_CCM_WRAP { cllval.val_key = CKK_YUBICO_AES192_CCM_WRAP; return KEYTYPE; }
CKK_YUBICO_AES256_CCM_WRAP|YUBICO_AES256_CCM_WRAP { cllval.val_key = CKK_YUBICO_AES256_CCM_WRAP; return KEYTYPE; }
lib/pkcs11_x509.c:361
- Typo in comment: “accomodate” should be “accommodate” (and the phrasing can drop “with”).
/* This is to accomodate with unreliable token libraries */
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 39 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (2)
lib/pkcs11_search.c:160
- pkcs11_alloc_fetch_all() only returns a boolean, but there are multiple failure modes (allocation failure, exceeding P11SEARCH_PREFETCH_MAX, and underlying C_FindObjects failure). Downstream callers currently map any false return to RC_ERROR_MEMORY/rc_error_memory, which misreports PKCS#11 failures as memory errors and can cause incorrect exit statuses.
/* pkcs11_alloc_fetch_all() prefetches every matching object handle into a
single heap-allocated array. This is required before a mutation
(cp/mv/rm/setattr): the search cursor cannot be safely iterated while the
underlying objects are being modified, so all handles are collected first and
the search is closed afterwards.
The buffer starts at P11SEARCH_PREFETCH_INITIAL entries and grows by doubling
up to P11SEARCH_PREFETCH_MAX entries; if more objects are found the function
bails out with an error.
On success, *out_handles points to an array of *out_count handles that the
caller must release with pkcs11_free_handle_array(). Returns true on
success, false on error. */
bool pkcs11_alloc_fetch_all(pkcs11Search *p11s, CK_OBJECT_HANDLE **out_handles, CK_ULONG *out_count)
lib/wrappedkey_parser.c:2220
- Grammar in this comment is incorrect ("There exist 5 templates").
if(ctx->pubkattribs->current_idx>=6) {
/* There exist 5 templates */
yyerror(ctx, "***Error: too many templates specified");
covertmatthew
left a comment
There was a problem hiding this comment.
@keldonin LGTM. CKA_TRUSTED and CKA_MODIFIABLE appear to be used correctly and the unbounded stack issue is fixed via removal of the configuration option.
- Updated wrappedkey_lexer.l to include new key types for Yubico AES wrapping (CKK_YUBICO_AES128_CCM_WRAP, CKK_YUBICO_AES192_CCM_WRAP, CKK_YUBICO_AES256_CCM_WRAP) with conditional compilation based on HAVE_YUBICO. - Modified wrappedkey_lexer.h to adjust line numbers for lexer definitions. - Refactored multiple source files (p11cat.c, p11cp.c, p11kcv.c, p11ls.c, p11more.c, p11mv.c, p11od.c, p11rm.c) to save the value of optind before opening the PKCS#11 library, ensuring correct argument parsing when using Yubico tokens. - Added a new script (with_yubico) for Yubico-specific configurations and usage, including handling of the Yubihsm library and configuration file paths.
…date related error handling following reported copilot findings
The YubiHSM PKCS#11 module reports CKA_KEY_TYPE as CK_UNAVAILABLE_INFORMATION with CKR_ATTRIBUTE_TYPE_INVALID on some keys (e.g. wrap keys), leaving pValue NULL. pkcs11_display_kcv() dereferenced it unconditionally, causing a crash on 'p11kcv seck/<wrapkey>'. Guard against a NULL/truncated CKA_KEY_TYPE value and skip the object instead.
…ext; correct Yubikey references
98ee696 to
c673bba
Compare
|
force-pushed after rebase on top of #90 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 40 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
CHANGELOG.md:19
- This CHANGELOG entry references a
PKCS11_PREFETCH_MAX_OBJECTSbound, but that symbol does not exist in the codebase. The actual bounds are implemented asP11SEARCH_PREFETCH_INITIAL/P11SEARCH_PREFETCH_MAXinlib/pkcs11_search.c(and are not currently configurable). Please update the changelog to reference the real limit or add the missing macro/option.
- `p11cp`, `p11mv`, `p11rm` and `p11setattr` now prefetch matching object handles before mutating, avoiding a live `C_FindObjects` cursor during changes (fails on some tokens, e.g. YubiHSM); bounded by `PKCS11_PREFETCH_MAX_OBJECTS`
|
|
||
| - support for the Yubico (YubiHSM) vendor key types `CKK_YUBICO_AES128/192/256_CCM_WRAP` (AES keys with the CCM-wrap capability): `p11ls` shows them as `aes(<size>,yubico-ccm-wrap)`, `p11od` decodes them, and their key type can be used in attribute templates. They cannot be generated with `p11keygen` (delegated capabilities are not expressible through PKCS#11). Enabled by default, disable with `--without-yubico` | ||
| - `with_yubico` wrapper script (and `yubico` case in `with_pkcs11_common`) for YubiHSM tokens | ||
| - `--with-prefetch-max-objects=NUM` configure option (default `1000`) |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 38 out of 40 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
CHANGELOG.md:18
- This changelog entry references
PKCS11_PREFETCH_MAX_OBJECTS, but the implementation uses an internal limit (P11SEARCH_PREFETCH_MAXinlib/pkcs11_search.c) and there is noPKCS11_PREFETCH_MAX_OBJECTSsymbol in the codebase. This makes the changelog misleading for readers trying to find/configure the limit.
- `p11cp`, `p11mv`, `p11rm` and `p11setattr` now prefetch matching object handles before mutating, avoiding a live `C_FindObjects` cursor during changes (fails on some tokens, e.g. YubiHSM); bounded by `PKCS11_PREFETCH_MAX_OBJECTS`
| /* allocate array */ | ||
| hndl_array = calloc(count, sizeof(CK_OBJECT_HANDLE)); | ||
|
|
||
| if(hndl_array==NULL) { | ||
| rc = rc_error_memory; | ||
| goto error; | ||
| } |