Skip to content

crypto: support OpenSSL STORE private keys#63949

Open
panva wants to merge 1 commit into
nodejs:mainfrom
panva:keyobject-stores
Open

crypto: support OpenSSL STORE private keys#63949
panva wants to merge 1 commit into
nodejs:mainfrom
panva:keyobject-stores

Conversation

@panva

@panva panva commented Jun 16, 2026

Copy link
Copy Markdown
Member

Note

Work in progress

Allow createPrivateKey() to load private keys from WHATWG URL objects through configured OpenSSL STORE providers. Reject built-in STORE loaders so this does not become a generic file or network URL loader, and gate the operation with the crypto.store permission.

Mark resulting private KeyObjects as store-backed. Public rewrapping and private-key export are rejected, while provider-backed private operations use the existing EVP paths.

Add hermetic STORE/keymgmt addon coverage and wire the pkcs11-provider SoftHSM test into shared-library CI for OpenSSL 3 and newer (< 4.0 actually due to current SoftHSM incompatibility with 4.0).

Examples

Load a provider-backed private key and sign with it:

import { createPrivateKey, sign } from 'node:crypto';

const key = createPrivateKey({
  key: new URL('pkcs11:token=node;object=signing-key;type=private'),
  passphrase: process.env.PKCS11_PIN,
});

const signature = sign('sha256', Buffer.from('payload'), key);

Use the Permission Model to bootstrap one signing key and then close the STORE-loading capability:

$ node --permission --allow-crypto-store app.mjs
import { createPrivateKey, sign } from 'node:crypto';

console.log(process.permission.has('crypto.store')); // true

const signingKey = createPrivateKey({
  key: new URL('pkcs11:token=node;object=signing-key;type=private'),
  passphrase: process.env.PKCS11_PIN,
});

process.permission.drop('crypto.store');
console.log(process.permission.has('crypto.store')); // false

export function signPayload(payload) {
  return sign('sha256', payload, signingKey);
}

Use a provider-backed private key with WebCrypto as a non-extractable CryptoKey:

import { createPrivateKey } from 'node:crypto';

const key = createPrivateKey({
  key: new URL('pkcs11:token=node;object=ed25519-key;type=private'),
  passphrase: process.env.PKCS11_PIN,
});

const cryptoKey = key.toCryptoKey('Ed25519', false, ['sign']);

const signature = await crypto.subtle.sign(
  'Ed25519',
  cryptoKey,
  new TextEncoder().encode('payload'),
);

@panva panva added the wip Issues and PRs that are still a work in progress. label Jun 16, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/actions
  • @nodejs/config
  • @nodejs/crypto
  • @nodejs/gyp
  • @nodejs/security-wg

@nodejs-github-bot nodejs-github-bot added lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Jun 16, 2026
@panva panva requested a review from tniessen June 17, 2026 09:04
Allow createPrivateKey() to load private keys from WHATWG URL
objects through configured OpenSSL STORE providers. Reject
built-in STORE loaders so this does not become a generic file or
network URL loader, and gate the operation with the crypto.store
permission.

Mark resulting private KeyObjects as store-backed. Public
rewrapping and private-key export are rejected, while
provider-backed private operations use the existing EVP paths.

Add hermetic STORE/keymgmt addon coverage and wire the
pkcs11-provider SoftHSM test into shared-library CI for OpenSSL 3
and newer.

Signed-off-by: Filip Skokan <panva.ip@gmail.com>
@panva panva force-pushed the keyobject-stores branch from 1c9a8b7 to 28a9da4 Compare June 17, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. wip Issues and PRs that are still a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants