first commit
This commit is contained in:
93
docs/security-stack/crypto/crypto-rsa/src/handle/registry.md
Normal file
93
docs/security-stack/crypto/crypto-rsa/src/handle/registry.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# handle/registry
|
||||
|
||||
## Purpose
|
||||
|
||||
Process-wide registry for RSA key-handle providers. Every HSM, KMS, OS
|
||||
keychain, or PKCS#11 bridge registers a provider once at startup; the
|
||||
registry resolves opaque `RsaKeyHandle` values to the matching provider
|
||||
at call time and dispatches `resolve` / `sign` / `decrypt` operations
|
||||
through it. Decouples consumer code from any specific hardware
|
||||
backend.
|
||||
|
||||
## Features
|
||||
|
||||
- Single in-process registry keyed by provider name
|
||||
- Idempotent re-registration of the same provider value
|
||||
- Conflicting registration of a different provider under the same name
|
||||
rejects with `INVALID_KEY`
|
||||
- `signWithHandle` / `decryptWithHandle` mirror the `RsaCryptoEngine`
|
||||
surface so handle consumers and engine consumers share the same
|
||||
scheme-options shape
|
||||
- `unregisterKeyHandleProvider` exposed for test cleanup
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
registerKeyHandleProvider,
|
||||
signWithHandle,
|
||||
} from "@suaveplan/crypto-rsa/handle";
|
||||
|
||||
registerKeyHandleProvider(myHsmProvider);
|
||||
const sig = await signWithHandle(
|
||||
{ provider: "my-hsm", id: "key-1" },
|
||||
message,
|
||||
{ scheme: "pkcs1v15", hash: "SHA-256" }
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
For test setups that need a clean registry per test:
|
||||
|
||||
```ts
|
||||
import {
|
||||
registerKeyHandleProvider,
|
||||
unregisterKeyHandleProvider,
|
||||
SoftwareRsaKeyHandleProvider,
|
||||
} from "@suaveplan/crypto-rsa/handle";
|
||||
|
||||
beforeEach(() => {
|
||||
registerKeyHandleProvider(new SoftwareRsaKeyHandleProvider());
|
||||
});
|
||||
afterEach(() => {
|
||||
unregisterKeyHandleProvider("software");
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `registerKeyHandleProvider(provider)`
|
||||
|
||||
- `provider: RsaKeyHandleProvider`
|
||||
- **throws** `CryptoRsaError(CRYPTO_RSA.INVALID_KEY)` on conflicting
|
||||
registration of a different provider under the same name
|
||||
|
||||
### `unregisterKeyHandleProvider(name)`
|
||||
|
||||
- `name: string`
|
||||
|
||||
### `resolveKeyHandle(handle): Promise<RsaPublicKey | RsaPrivateKey>`
|
||||
|
||||
- **throws** `CryptoRsaError(CRYPTO_RSA.INVALID_KEY)` when no provider
|
||||
is registered under the handle's `provider` name
|
||||
|
||||
### `signWithHandle(handle, message, options): Promise<Uint8Array>`
|
||||
|
||||
### `decryptWithHandle(handle, ciphertext, options): Promise<Uint8Array>`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The registry is a module-level `Map<string, RsaKeyHandleProvider>`.
|
||||
The chosen scope is process-lifetime; if cross-process or per-vault
|
||||
isolation is required, callers must wrap their own dispatch layer.
|
||||
- Idempotent registration of the same provider value (object identity
|
||||
comparison) is a no-op so that import-once-then-register patterns
|
||||
work without per-import side effects.
|
||||
- Conflicting registration (two different provider objects with the
|
||||
same name) raises a typed error instead of silently winning — this
|
||||
is to detect copy-paste mistakes between adapters during integration.
|
||||
- Handle resolution failures throw `INVALID_KEY` because from the
|
||||
caller's perspective the supplied handle was not valid (the
|
||||
underlying cause — provider unregistered, id unknown — is captured
|
||||
in the error context).
|
||||
Reference in New Issue
Block a user