@sebastienrousseau/crypto-kms 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +8 -0
- package/README.md +320 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/providers/aws.d.ts +36 -0
- package/dist/providers/aws.d.ts.map +1 -0
- package/dist/providers/aws.js +214 -0
- package/dist/providers/azure.d.ts +29 -0
- package/dist/providers/azure.d.ts.map +1 -0
- package/dist/providers/azure.js +52 -0
- package/dist/providers/gcp.d.ts +31 -0
- package/dist/providers/gcp.d.ts.map +1 -0
- package/dist/providers/gcp.js +53 -0
- package/dist/providers/local.d.ts +30 -0
- package/dist/providers/local.d.ts.map +1 -0
- package/dist/providers/local.js +139 -0
- package/dist/providers/pkcs11.d.ts +53 -0
- package/dist/providers/pkcs11.d.ts.map +1 -0
- package/dist/providers/pkcs11.js +165 -0
- package/dist/providers/vault.d.ts +34 -0
- package/dist/providers/vault.d.ts.map +1 -0
- package/dist/providers/vault.js +63 -0
- package/dist/providers/versioned-key.d.ts +26 -0
- package/dist/providers/versioned-key.d.ts.map +1 -0
- package/dist/providers/versioned-key.js +141 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/package.json +71 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/sebastienrousseau/crypto-service/main/assets/crypto-kms-logo.svg" alt="crypto-kms logo" width="360" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">@sebastienrousseau/crypto-kms</h1>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
Unified Key Management Service interface. AWS KMS and an in-memory local provider are implemented; GCP, Azure and Vault are stubs.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<a href="https://github.com/sebastienrousseau/crypto-service/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/crypto-service/ci.yml?branch=main&style=for-the-badge&logo=github" alt="Build" /></a>
|
|
15
|
+
<a href="https://coveralls.io/github/sebastienrousseau/crypto-service?branch=main"><img src="https://img.shields.io/coveralls/github/sebastienrousseau/crypto-service?branch=main&style=for-the-badge" alt="Coverage" /></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@sebastienrousseau/crypto-kms"><img src="https://img.shields.io/npm/v/@sebastienrousseau/crypto-kms.svg?style=for-the-badge&color=f14041&logo=npm" alt="Registry" /></a>
|
|
17
|
+
<a href="https://sebastienrousseau.github.io/crypto-service/"><img src="https://img.shields.io/badge/docs-TypeDoc-blue.svg?style=for-the-badge&labelColor=555555&logo=typescript" alt="Docs" /></a>
|
|
18
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/crypto-service" title="ossf-scorecard"><img src="https://img.shields.io/badge/OpenSSF-Scorecard-blue?style=for-the-badge&logo=openssf" alt="OpenSSF Scorecard" /></a>
|
|
19
|
+
<a href="https://github.com/sebastienrousseau/crypto-service/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg?style=for-the-badge" alt="License: Apache-2.0 OR MIT" /></a>
|
|
20
|
+
<a href="https://github.com/sebastienrousseau/crypto-service/blob/main/docs/POLICIES.md"><img src="https://img.shields.io/badge/Node.js-%3E%3D22-93450a.svg?style=for-the-badge&logo=node.js" alt="Node.js 22 or newer" /></a>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Contents
|
|
26
|
+
|
|
27
|
+
**Getting started**
|
|
28
|
+
|
|
29
|
+
- [Install](#install) — installation via pnpm, npm, or yarn
|
|
30
|
+
- [Requirements](#requirements) — runtime floor and environment prerequisites
|
|
31
|
+
- [Quick Start](#quick-start) — minimal working usage sample
|
|
32
|
+
|
|
33
|
+
**The Crypto Service ecosystem**
|
|
34
|
+
|
|
35
|
+
- [The Crypto Service ecosystem](#the-crypto-service-ecosystem) — full 14-package suite overview
|
|
36
|
+
|
|
37
|
+
**Package reference**
|
|
38
|
+
|
|
39
|
+
- [Reference & Usage](#overview) — features, configuration, and capabilities
|
|
40
|
+
- [Examples](#examples) — runnable sample code
|
|
41
|
+
|
|
42
|
+
**Operational**
|
|
43
|
+
|
|
44
|
+
- [Development](#development) — build, lint, format, and test targets
|
|
45
|
+
- [Security](#security) — vulnerability disclosure and cryptographic invariants
|
|
46
|
+
- [Documentation](#documentation) — TypeDoc API docs and ecosystem guides
|
|
47
|
+
- [Stability guarantees](#stability-guarantees) — SemVer axis and release policy
|
|
48
|
+
- [License](#license)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm add @sebastienrousseau/crypto-kms
|
|
56
|
+
# or
|
|
57
|
+
npm install @sebastienrousseau/crypto-kms
|
|
58
|
+
# or
|
|
59
|
+
yarn add @sebastienrousseau/crypto-kms
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Requirements
|
|
67
|
+
|
|
68
|
+
- **Node.js**: `^22.0.0` or `>=24.0.0` (active and maintenance LTS releases)
|
|
69
|
+
- **Package Manager**: `pnpm >=9` (recommended) or `npm >=10`
|
|
70
|
+
- **TypeScript**: `>=5.0` (when compiling with TypeScript)
|
|
71
|
+
|
|
72
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Quick Start
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { LocalKmsProvider } from "@sebastienrousseau/crypto-kms";
|
|
80
|
+
|
|
81
|
+
const kms = new LocalKmsProvider();
|
|
82
|
+
const key = await kms.createKey("aes-256-gcm", "encrypt");
|
|
83
|
+
const encrypted = await kms.encrypt(
|
|
84
|
+
key.keyId,
|
|
85
|
+
new TextEncoder().encode("secret"),
|
|
86
|
+
);
|
|
87
|
+
const decrypted = await kms.decrypt(key.keyId, encrypted.ciphertext);
|
|
88
|
+
console.log(new TextDecoder().decode(decrypted.plaintext)); // "secret"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## The Crypto Service ecosystem
|
|
96
|
+
|
|
97
|
+
Crypto Service provides a complete cryptography stack across 14 specialized packages:
|
|
98
|
+
|
|
99
|
+
| Package | Role | Description |
|
|
100
|
+
| :-------------------------------------------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
|
|
101
|
+
| [`@sebastienrousseau/crypto-api`](../crypto-api) | API Schemas | Shared TypeScript types and utilities for the Crypto Service Suite, defining the canonical API surface. |
|
|
102
|
+
| [`@sebastienrousseau/crypto-cli`](../crypto-cli) | Terminal CLI | An interactive command-line interface for cryptographic operations, supporting both legacy OpenPGP and modern post-quantum algorithms. |
|
|
103
|
+
| [`@sebastienrousseau/crypto-edge`](../crypto-edge) | Edge Runtime | Edge-runtime cryptographic operations using the Web Crypto API, optimized for Cloudflare Workers, Vercel Edge, and Deno. |
|
|
104
|
+
| **[`@sebastienrousseau/crypto-kms`](../crypto-kms)** _(this package)_ | **Cloud KMS** | **Unified KMS interface: AWS KMS and local providers implemented; GCP, Azure and Vault are stubs.** |
|
|
105
|
+
| [`@sebastienrousseau/crypto-lib`](../crypto-lib) | Core Library | A modern cryptographic library for TypeScript, with post-quantum support, zero unsafe dependencies, and 100% test coverage. |
|
|
106
|
+
| [`@sebastienrousseau/crypto-middleware`](../crypto-middleware) | Middleware | Framework-agnostic cryptographic middleware for Express, Fastify, and Koa applications. |
|
|
107
|
+
| [`@sebastienrousseau/crypto-prisma`](../crypto-prisma) | ORM Adapter | Transparent field-level encryption extension for Prisma Client, using XChaCha20-Poly1305. |
|
|
108
|
+
| [`@sebastienrousseau/crypto-react`](../crypto-react) | React Hooks | React hooks and context provider for client-side cryptographic operations with zero boilerplate. |
|
|
109
|
+
| [`@sebastienrousseau/crypto-sdk`](../crypto-sdk) | Client SDK | A zero-dependency, typed HTTP client for the Crypto Service REST API, with full post-quantum support. |
|
|
110
|
+
| [`@sebastienrousseau/crypto-server`](../crypto-server) | HTTP API | A hardened Fastify REST API for cryptographic operations, with rate limiting, OpenAPI schemas, and post-quantum endpoints. |
|
|
111
|
+
| [`@sebastienrousseau/crypto-testing`](../crypto-testing) | Test Support | Deterministic keys, fast mocks, and test fixtures for crypto-lib |
|
|
112
|
+
| [`@sebastienrousseau/crypto-typeorm`](../crypto-typeorm) | ORM Adapter | TypeORM column-level encryption with a single decorator, powered by crypto-lib. |
|
|
113
|
+
| [`@sebastienrousseau/crypto-vue`](../crypto-vue) | Vue Composables | Vue 3 composables for client-side cryptography |
|
|
114
|
+
| [`@sebastienrousseau/crypto-wasm`](../crypto-wasm) | Acceleration | Placeholder for a WebAssembly accelerator; contains no WebAssembly code yet. |
|
|
115
|
+
|
|
116
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Overview
|
|
121
|
+
|
|
122
|
+
crypto-kms defines a unified `KmsProvider` interface for key
|
|
123
|
+
creation, encryption, decryption, signing, verification, rotation
|
|
124
|
+
and data-key generation. Two providers are implemented: AWS KMS and
|
|
125
|
+
an in-memory local provider. The GCP, Azure and HashiCorp Vault
|
|
126
|
+
providers are stubs: every method rejects with `Not implemented`.
|
|
127
|
+
The PKCS#11 provider is an in-memory software simulation for tests
|
|
128
|
+
(see below); it does not talk to an HSM.
|
|
129
|
+
|
|
130
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
131
|
+
|
|
132
|
+
## Providers
|
|
133
|
+
|
|
134
|
+
| Provider | Class | Backend | Status | Peer Dependency |
|
|
135
|
+
| :---------- | :------------------ | :------------------------- | :------------------------------------ | :--------------------- |
|
|
136
|
+
| **AWS** | `AwsKmsProvider` | AWS Key Management Service | Implemented | `@aws-sdk/client-kms` |
|
|
137
|
+
| **GCP** | `GcpKmsProvider` | Google Cloud KMS | Stub (rejects `Not implemented`) | `@google-cloud/kms` |
|
|
138
|
+
| **Azure** | `AzureKmsProvider` | Azure Key Vault | Stub (rejects `Not implemented`) | `@azure/keyvault-keys` |
|
|
139
|
+
| **Vault** | `VaultKmsProvider` | HashiCorp Vault Transit | Stub (rejects `Not implemented`) | None |
|
|
140
|
+
| **Local** | `LocalKmsProvider` | In-memory (crypto-lib) | Implemented | None |
|
|
141
|
+
| **PKCS#11** | `Pkcs11HsmProvider` | None (in-memory) | Software simulation; `simulate: true` | None |
|
|
142
|
+
|
|
143
|
+
`Pkcs11HsmProvider` has no PKCS#11 binding: it never loads a module,
|
|
144
|
+
accepts any PIN, keeps keys in process memory and reports
|
|
145
|
+
`fipsLevel: "none (software simulation)"`. Its constructor throws
|
|
146
|
+
unless you pass `{ simulate: true }`. Use it only in tests.
|
|
147
|
+
|
|
148
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
149
|
+
|
|
150
|
+
## API Reference
|
|
151
|
+
|
|
152
|
+
Every provider exposes the `KmsProvider` interface:
|
|
153
|
+
|
|
154
|
+
| Method | Description |
|
|
155
|
+
| :------------------------------------------- | :------------------------------------------- |
|
|
156
|
+
| `listKeys(filters?)` | List all managed keys, with optional filters |
|
|
157
|
+
| `getKey(keyId)` | Retrieve metadata for a specific key |
|
|
158
|
+
| `createKey(algorithm, usage, metadata?)` | Create a new managed key |
|
|
159
|
+
| `enableKey(keyId)` | Enable a disabled key |
|
|
160
|
+
| `disableKey(keyId)` | Disable a key (soft delete) |
|
|
161
|
+
| `scheduleKeyDeletion(keyId, days?)` | Schedule a key for deletion |
|
|
162
|
+
| `encrypt(keyId, plaintext, context?)` | Encrypt plaintext with a managed key |
|
|
163
|
+
| `decrypt(keyId, ciphertext, context?)` | Decrypt ciphertext with a managed key |
|
|
164
|
+
| `sign(keyId, data, algorithm?)` | Sign data with a managed signing key |
|
|
165
|
+
| `verify(keyId, data, signature, algorithm?)` | Verify a signature |
|
|
166
|
+
| `rotateKey(keyId)` | Add a new current key version |
|
|
167
|
+
| `destroyKeyVersion?(keyId, version)` | Destroy a retired version (optional method) |
|
|
168
|
+
| `generateDataKey(keyId, keySpec?)` | Generate a wrapped data encryption key |
|
|
169
|
+
|
|
170
|
+
### Key rotation and versions
|
|
171
|
+
|
|
172
|
+
`LocalKmsProvider` and `Pkcs11HsmProvider` keep every version of a key.
|
|
173
|
+
`rotateKey` adds a new current version; it does not replace the old
|
|
174
|
+
material. New ciphertext and signatures use the current version, and
|
|
175
|
+
each ciphertext records the version that produced it, so data encrypted
|
|
176
|
+
before a rotation still decrypts and signatures made before it still
|
|
177
|
+
verify. `getKey` reports `currentVersion`; `encrypt` and `decrypt`
|
|
178
|
+
report `keyVersion`.
|
|
179
|
+
|
|
180
|
+
A version stays usable until you destroy it with
|
|
181
|
+
`destroyKeyVersion(keyId, version)`. After that, ciphertext from that
|
|
182
|
+
version rejects with `VERSION_DESTROYED` and its signatures no longer
|
|
183
|
+
verify. The current version cannot be destroyed; rotate first.
|
|
184
|
+
`disableKey` and `scheduleKeyDeletion` still block every operation on
|
|
185
|
+
the key, all versions included.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
const key = await kms.createKey("aes-256-gcm", "encrypt");
|
|
189
|
+
const old = await kms.encrypt(key.keyId, data); // old.keyVersion === 1
|
|
190
|
+
await kms.rotateKey(key.keyId); // currentVersion === 2
|
|
191
|
+
await kms.decrypt(key.keyId, old.ciphertext); // still decrypts with version 1
|
|
192
|
+
await kms.destroyKeyVersion(key.keyId, 1); // version 1 is gone for good
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
The ciphertext of these two providers is the base64 of: a format byte
|
|
196
|
+
(`0x01`), the key version (4 bytes, big-endian), the AES-GCM IV (12
|
|
197
|
+
bytes), the tag (16 bytes) and the AES-256-GCM ciphertext. Ciphertext
|
|
198
|
+
produced by 0.0.6 and earlier is not accepted; neither provider persists
|
|
199
|
+
keys, so none can outlive the process that made it.
|
|
200
|
+
|
|
201
|
+
### Encryption context
|
|
202
|
+
|
|
203
|
+
The encryption context is bound to the ciphertext as AES-GCM additional
|
|
204
|
+
authenticated data. It is canonicalised first (entries sorted by key),
|
|
205
|
+
so `{ a: "1", b: "2" }` and `{ b: "2", a: "1" }` are the same context.
|
|
206
|
+
Values must be strings; anything else rejects with `INVALID_ARGUMENT`.
|
|
207
|
+
An empty context is the same as no context.
|
|
208
|
+
|
|
209
|
+
### Errors
|
|
210
|
+
|
|
211
|
+
Providers reject with `KmsError`, which extends `Error` and carries a
|
|
212
|
+
`code` (and the `keyId` when there is one). Branch on the code, not the
|
|
213
|
+
message:
|
|
214
|
+
|
|
215
|
+
| Code | Meaning |
|
|
216
|
+
| :------------------- | :------------------------------------------------------------- |
|
|
217
|
+
| `NOT_FOUND` | Unknown key, or a ciphertext names a version the key never had |
|
|
218
|
+
| `DISABLED` | The key is disabled or scheduled for deletion |
|
|
219
|
+
| `INVALID_USAGE` | The key's usage does not allow the operation |
|
|
220
|
+
| `INVALID_ARGUMENT` | Malformed argument, or destroying the current version |
|
|
221
|
+
| `INVALID_CIPHERTEXT` | Truncated ciphertext or an unknown format |
|
|
222
|
+
| `DECRYPTION_FAILED` | Wrong context, wrong key, or tampered ciphertext |
|
|
223
|
+
| `VERSION_DESTROYED` | The ciphertext's key version has been destroyed |
|
|
224
|
+
| `NOT_IMPLEMENTED` | Stub provider (GCP, Azure, Vault) |
|
|
225
|
+
| `DEPENDENCY_MISSING` | The AWS SDK peer dependency is not installed |
|
|
226
|
+
|
|
227
|
+
Errors raised by the AWS SDK itself are passed through unchanged. No
|
|
228
|
+
provider method takes a timeout or an `AbortSignal` yet.
|
|
229
|
+
|
|
230
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
231
|
+
|
|
232
|
+
## Authentication
|
|
233
|
+
|
|
234
|
+
| Provider | Credentials |
|
|
235
|
+
| :-------- | :--------------------------------------------------------------------------------- |
|
|
236
|
+
| **AWS** | Pass `credentials` in `AwsKmsOptions`, or rely on the default AWS credential chain |
|
|
237
|
+
| **GCP** | Not applicable yet (stub provider) |
|
|
238
|
+
| **Azure** | Not applicable yet (stub provider) |
|
|
239
|
+
| **Vault** | Not applicable yet (stub provider) |
|
|
240
|
+
| **Local** | No authentication required |
|
|
241
|
+
|
|
242
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
243
|
+
|
|
244
|
+
## Examples
|
|
245
|
+
|
|
246
|
+
All examples are self-contained TypeScript files in the `examples/`
|
|
247
|
+
directory. Run any example with:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
npx ts-node examples/<name>.ts
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
| Category | Example | Purpose |
|
|
254
|
+
| :------- | :---------------------------------- | :------------------------------------------------------- |
|
|
255
|
+
| Local | [local.ts](examples/local.ts) | Create keys, encrypt/decrypt with the in-memory provider |
|
|
256
|
+
| AWS | [aws.ts](examples/aws.ts) | AWS KMS setup and usage pattern |
|
|
257
|
+
| Envelope | [envelope.ts](examples/envelope.ts) | Envelope encryption with `generateDataKey` |
|
|
258
|
+
| Rotation | [rotation.ts](examples/rotation.ts) | Rotate, decrypt old data, destroy a retired version |
|
|
259
|
+
| Multi | [multi.ts](examples/multi.ts) | Provider-agnostic code across multiple backends |
|
|
260
|
+
|
|
261
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
262
|
+
|
|
263
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Development
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
pnpm --filter @sebastienrousseau/crypto-kms run build
|
|
271
|
+
pnpm --filter @sebastienrousseau/crypto-kms run test
|
|
272
|
+
pnpm --filter @sebastienrousseau/crypto-kms run lint
|
|
273
|
+
pnpm --filter @sebastienrousseau/crypto-kms run format
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
All 18 packages in the Crypto Service workspace maintain a **100% coverage floor** across statements, branches, functions, and lines.
|
|
277
|
+
|
|
278
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Security
|
|
283
|
+
|
|
284
|
+
Report vulnerabilities privately via [GitHub Security Advisories](https://github.com/sebastienrousseau/crypto-service/security/advisories) or according to [`SECURITY.md`](../../SECURITY.md). Never report security issues publicly.
|
|
285
|
+
|
|
286
|
+
The local and simulated PKCS#11 providers run AES-256-GCM through Node.js `crypto` and Ed25519 through crypto-lib (`@noble/curves`). Neither is a validated cryptographic module, and neither zeroes key material held in memory.
|
|
287
|
+
|
|
288
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Documentation
|
|
293
|
+
|
|
294
|
+
- [Full Suite Documentation](https://sebastienrousseau.github.io/crypto-service/)
|
|
295
|
+
- [API Reference (TypeDoc)](https://sebastienrousseau.github.io/crypto-service/)
|
|
296
|
+
- [Developer Guide](../../DEVELOPMENT.md)
|
|
297
|
+
- [Security Policy](../../SECURITY.md)
|
|
298
|
+
- [Architecture & Design](../../ARCHITECTURE.md)
|
|
299
|
+
|
|
300
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Stability guarantees
|
|
305
|
+
|
|
306
|
+
Versions advance strictly one step at a time on the `0.0.x` line (`v0.0.1` → `v0.0.2` → `v0.0.3` ... → `v0.0.999` → `v0.1.0`). Work for every release iteration begins on a dedicated `feat/v<version>` branch.
|
|
307
|
+
|
|
308
|
+
All 18 packages in the workspace move in lockstep. Public API signatures, cipher output formats, and serialization schemas are strictly versioned. Breaking changes to serialized formats or algorithm defaults are considered major breaking changes. Minimum toolchain upgrades (e.g. Node.js LTS floor) are governed by [POLICIES.md](../../docs/POLICIES.md).
|
|
309
|
+
|
|
310
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
Dual-licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) or [MIT](https://opensource.org/licenses/MIT), at your option.
|
|
317
|
+
|
|
318
|
+
Copyright (c) 2022-2026 Sebastien Rousseau and The Crypto Service Suite contributors.
|
|
319
|
+
|
|
320
|
+
<p align="right"><a href="#contents">Back to Top</a></p>
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type KmsErrorCode = "NOT_FOUND" | "DISABLED" | "INVALID_USAGE" | "INVALID_ARGUMENT" | "INVALID_CIPHERTEXT" | "DECRYPTION_FAILED" | "VERSION_DESTROYED" | "NOT_IMPLEMENTED" | "DEPENDENCY_MISSING";
|
|
2
|
+
export declare class KmsError extends Error {
|
|
3
|
+
readonly name = "KmsError";
|
|
4
|
+
readonly code: KmsErrorCode;
|
|
5
|
+
readonly keyId: string | undefined;
|
|
6
|
+
constructor(code: KmsErrorCode, message: string, keyId?: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AA0BA,MAAM,MAAM,YAAY,GACpB,WAAW,GACX,UAAU,GACV,eAAe,GACf,kBAAkB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,CAAC;AAmBzB,qBAAa,QAAS,SAAQ,KAAK;IAEjC,SAAkB,IAAI,cAAc;IAEpC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAE5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;gBAGvB,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;CAKhE"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KmsError = void 0;
|
|
4
|
+
class KmsError extends Error {
|
|
5
|
+
name = "KmsError";
|
|
6
|
+
code;
|
|
7
|
+
keyId;
|
|
8
|
+
constructor(code, message, keyId) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.keyId = keyId;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.KmsError = KmsError;
|
|
15
|
+
//# sourceMappingURL=errors.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type { KmsProvider, KmsKeyMetadata, KmsEncryptResult, KmsDecryptResult, KmsSignResult, } from "./types";
|
|
2
|
+
export { KmsError } from "./errors";
|
|
3
|
+
export type { KmsErrorCode } from "./errors";
|
|
4
|
+
export { AwsKmsProvider } from "./providers/aws";
|
|
5
|
+
export type { AwsKmsOptions } from "./providers/aws";
|
|
6
|
+
export { GcpKmsProvider } from "./providers/gcp";
|
|
7
|
+
export type { GcpKmsOptions } from "./providers/gcp";
|
|
8
|
+
export { AzureKmsProvider } from "./providers/azure";
|
|
9
|
+
export type { AzureKmsOptions } from "./providers/azure";
|
|
10
|
+
export { VaultKmsProvider } from "./providers/vault";
|
|
11
|
+
export type { VaultKmsOptions } from "./providers/vault";
|
|
12
|
+
export { LocalKmsProvider } from "./providers/local";
|
|
13
|
+
export { Pkcs11HsmProvider } from "./providers/pkcs11";
|
|
14
|
+
export type { Pkcs11HsmOptions, HsmSessionInfo } from "./providers/pkcs11";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,YAAY,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Pkcs11HsmProvider = exports.LocalKmsProvider = exports.VaultKmsProvider = exports.AzureKmsProvider = exports.GcpKmsProvider = exports.AwsKmsProvider = exports.KmsError = void 0;
|
|
4
|
+
var errors_1 = require("./errors");
|
|
5
|
+
Object.defineProperty(exports, "KmsError", { enumerable: true, get: function () { return errors_1.KmsError; } });
|
|
6
|
+
var aws_1 = require("./providers/aws");
|
|
7
|
+
Object.defineProperty(exports, "AwsKmsProvider", { enumerable: true, get: function () { return aws_1.AwsKmsProvider; } });
|
|
8
|
+
var gcp_1 = require("./providers/gcp");
|
|
9
|
+
Object.defineProperty(exports, "GcpKmsProvider", { enumerable: true, get: function () { return gcp_1.GcpKmsProvider; } });
|
|
10
|
+
var azure_1 = require("./providers/azure");
|
|
11
|
+
Object.defineProperty(exports, "AzureKmsProvider", { enumerable: true, get: function () { return azure_1.AzureKmsProvider; } });
|
|
12
|
+
var vault_1 = require("./providers/vault");
|
|
13
|
+
Object.defineProperty(exports, "VaultKmsProvider", { enumerable: true, get: function () { return vault_1.VaultKmsProvider; } });
|
|
14
|
+
var local_1 = require("./providers/local");
|
|
15
|
+
Object.defineProperty(exports, "LocalKmsProvider", { enumerable: true, get: function () { return local_1.LocalKmsProvider; } });
|
|
16
|
+
var pkcs11_1 = require("./providers/pkcs11");
|
|
17
|
+
Object.defineProperty(exports, "Pkcs11HsmProvider", { enumerable: true, get: function () { return pkcs11_1.Pkcs11HsmProvider; } });
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { KmsProvider, KmsKeyMetadata, KmsEncryptResult, KmsDecryptResult, KmsSignResult } from "../types";
|
|
2
|
+
export interface AwsKmsOptions {
|
|
3
|
+
region: string;
|
|
4
|
+
credentials?: {
|
|
5
|
+
accessKeyId: string;
|
|
6
|
+
secretAccessKey: string;
|
|
7
|
+
sessionToken?: string;
|
|
8
|
+
};
|
|
9
|
+
endpoint?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class AwsKmsProvider implements KmsProvider {
|
|
12
|
+
readonly name = "aws";
|
|
13
|
+
private readonly options;
|
|
14
|
+
private client;
|
|
15
|
+
constructor(options: AwsKmsOptions);
|
|
16
|
+
private getClient;
|
|
17
|
+
listKeys(_filters?: {
|
|
18
|
+
usage?: string;
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
}): Promise<KmsKeyMetadata[]>;
|
|
21
|
+
getKey(keyId: string): Promise<KmsKeyMetadata>;
|
|
22
|
+
createKey(algorithm: string, usage: "encrypt" | "sign" | "wrap", metadata?: Record<string, string>): Promise<KmsKeyMetadata>;
|
|
23
|
+
enableKey(keyId: string): Promise<void>;
|
|
24
|
+
disableKey(keyId: string): Promise<void>;
|
|
25
|
+
scheduleKeyDeletion(keyId: string, pendingWindowDays?: number): Promise<void>;
|
|
26
|
+
encrypt(keyId: string, plaintext: Uint8Array, context?: Record<string, string>): Promise<KmsEncryptResult>;
|
|
27
|
+
decrypt(keyId: string, ciphertext: string, context?: Record<string, string>): Promise<KmsDecryptResult>;
|
|
28
|
+
sign(keyId: string, data: Uint8Array, algorithm?: string): Promise<KmsSignResult>;
|
|
29
|
+
verify(keyId: string, data: Uint8Array, signature: string, algorithm?: string): Promise<boolean>;
|
|
30
|
+
rotateKey(keyId: string): Promise<KmsKeyMetadata>;
|
|
31
|
+
generateDataKey(keyId: string, keySpec?: string): Promise<{
|
|
32
|
+
plaintext: Uint8Array;
|
|
33
|
+
ciphertext: string;
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=aws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aws.d.ts","sourceRoot":"","sources":["../../src/providers/aws.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACd,MAAM,UAAU,CAAC;AAkBlB,MAAM,WAAW,aAAa;IAE5B,MAAM,EAAE,MAAM,CAAC;IAEf,WAAW,CAAC,EAAE;QAEZ,WAAW,EAAE,MAAM,CAAC;QAEpB,eAAe,EAAE,MAAM,CAAC;QAExB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAqBD,qBAAa,cAAe,YAAW,WAAW;IAEhD,QAAQ,CAAC,IAAI,SAAS;IAEtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC,OAAO,CAAC,MAAM,CAAsB;gBAGxB,OAAO,EAAE,aAAa;YAMpB,SAAS;IAqBjB,QAAQ,CAAC,QAAQ,CAAC,EAAE;QACxB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAevB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAgB9C,SAAS,CACb,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,EAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,cAAc,CAAC;IA+BpB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxC,mBAAmB,CACvB,KAAK,EAAE,MAAM,EACb,iBAAiB,SAAK,GACrB,OAAO,CAAC,IAAI,CAAC;IAYV,OAAO,CACX,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,UAAU,EACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC;IAqBtB,OAAO,CACX,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC;IAiBtB,IAAI,CACR,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,SAAS,SAAuB,GAC/B,OAAO,CAAC,aAAa,CAAC;IAmBnB,MAAM,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,SAAuB,GAC/B,OAAO,CAAC,OAAO,CAAC;IAgBb,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAQjD,eAAe,CACnB,KAAK,EAAE,MAAM,EACb,OAAO,SAAY,GAClB,OAAO,CAAC;QAET,SAAS,EAAE,UAAU,CAAC;QAEtB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CAcH"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AwsKmsProvider = void 0;
|
|
37
|
+
const errors_1 = require("../errors");
|
|
38
|
+
const AWS_SDK_MISSING = "AWS KMS requires @aws-sdk/client-kms. Install it: npm install @aws-sdk/client-kms";
|
|
39
|
+
class AwsKmsProvider {
|
|
40
|
+
name = "aws";
|
|
41
|
+
options;
|
|
42
|
+
client;
|
|
43
|
+
constructor(options) {
|
|
44
|
+
this.options = options;
|
|
45
|
+
this.client = null;
|
|
46
|
+
}
|
|
47
|
+
async getClient() {
|
|
48
|
+
if (!this.client) {
|
|
49
|
+
try {
|
|
50
|
+
const mod = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
51
|
+
const config = { region: this.options.region };
|
|
52
|
+
if (this.options.credentials) {
|
|
53
|
+
config.credentials = this.options.credentials;
|
|
54
|
+
}
|
|
55
|
+
if (this.options.endpoint) {
|
|
56
|
+
config.endpoint = this.options.endpoint;
|
|
57
|
+
}
|
|
58
|
+
this.client = new mod.KMSClient(config);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new errors_1.KmsError("DEPENDENCY_MISSING", AWS_SDK_MISSING);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return this.client;
|
|
65
|
+
}
|
|
66
|
+
async listKeys(_filters) {
|
|
67
|
+
const client = await this.getClient();
|
|
68
|
+
const { ListKeysCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
69
|
+
const result = await client.send(new ListKeysCommand({}));
|
|
70
|
+
return (result.Keys ?? []).map((k) => ({
|
|
71
|
+
keyId: k.KeyId ?? "",
|
|
72
|
+
algorithm: "unknown",
|
|
73
|
+
usage: "encrypt",
|
|
74
|
+
createdAt: new Date().toISOString(),
|
|
75
|
+
enabled: true,
|
|
76
|
+
provider: "aws",
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
async getKey(keyId) {
|
|
80
|
+
const client = await this.getClient();
|
|
81
|
+
const { DescribeKeyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
82
|
+
const result = await client.send(new DescribeKeyCommand({ KeyId: keyId }));
|
|
83
|
+
const meta = result.KeyMetadata;
|
|
84
|
+
return {
|
|
85
|
+
keyId: meta?.KeyId ?? keyId,
|
|
86
|
+
algorithm: meta?.KeySpec ?? "unknown",
|
|
87
|
+
usage: meta?.KeyUsage === "SIGN_VERIFY" ? "sign" : "encrypt",
|
|
88
|
+
createdAt: meta?.CreationDate?.toISOString() ?? new Date().toISOString(),
|
|
89
|
+
enabled: meta?.Enabled ?? true,
|
|
90
|
+
provider: "aws",
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async createKey(algorithm, usage, metadata) {
|
|
94
|
+
const client = await this.getClient();
|
|
95
|
+
const { CreateKeyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
96
|
+
const keySpec = algorithm.toUpperCase().replace(/-/g, "_");
|
|
97
|
+
const result = await client.send(new CreateKeyCommand({
|
|
98
|
+
KeyUsage: usage === "sign" ? "SIGN_VERIFY" : "ENCRYPT_DECRYPT",
|
|
99
|
+
KeySpec: keySpec,
|
|
100
|
+
...(metadata
|
|
101
|
+
? {
|
|
102
|
+
Tags: Object.entries(metadata).map(([k, v]) => ({
|
|
103
|
+
TagKey: k,
|
|
104
|
+
TagValue: v,
|
|
105
|
+
})),
|
|
106
|
+
}
|
|
107
|
+
: {}),
|
|
108
|
+
}));
|
|
109
|
+
return {
|
|
110
|
+
keyId: result.KeyMetadata?.KeyId ?? "",
|
|
111
|
+
algorithm,
|
|
112
|
+
usage,
|
|
113
|
+
createdAt: result.KeyMetadata?.CreationDate?.toISOString() ??
|
|
114
|
+
new Date().toISOString(),
|
|
115
|
+
enabled: true,
|
|
116
|
+
provider: "aws",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
async enableKey(keyId) {
|
|
120
|
+
const client = await this.getClient();
|
|
121
|
+
const { EnableKeyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
122
|
+
await client.send(new EnableKeyCommand({ KeyId: keyId }));
|
|
123
|
+
}
|
|
124
|
+
async disableKey(keyId) {
|
|
125
|
+
const client = await this.getClient();
|
|
126
|
+
const { DisableKeyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
127
|
+
await client.send(new DisableKeyCommand({ KeyId: keyId }));
|
|
128
|
+
}
|
|
129
|
+
async scheduleKeyDeletion(keyId, pendingWindowDays = 30) {
|
|
130
|
+
const client = await this.getClient();
|
|
131
|
+
const { ScheduleKeyDeletionCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
132
|
+
await client.send(new ScheduleKeyDeletionCommand({
|
|
133
|
+
KeyId: keyId,
|
|
134
|
+
PendingWindowInDays: pendingWindowDays,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
async encrypt(keyId, plaintext, context) {
|
|
138
|
+
const client = await this.getClient();
|
|
139
|
+
const { EncryptCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
140
|
+
const result = await client.send(new EncryptCommand({
|
|
141
|
+
KeyId: keyId,
|
|
142
|
+
Plaintext: plaintext,
|
|
143
|
+
...(context ? { EncryptionContext: context } : {}),
|
|
144
|
+
}));
|
|
145
|
+
const out = {
|
|
146
|
+
ciphertext: Buffer.from(result.CiphertextBlob).toString("base64"),
|
|
147
|
+
keyId: result.KeyId ?? keyId,
|
|
148
|
+
};
|
|
149
|
+
if (context) {
|
|
150
|
+
out.context = context;
|
|
151
|
+
}
|
|
152
|
+
return out;
|
|
153
|
+
}
|
|
154
|
+
async decrypt(keyId, ciphertext, context) {
|
|
155
|
+
const client = await this.getClient();
|
|
156
|
+
const { DecryptCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
157
|
+
const result = await client.send(new DecryptCommand({
|
|
158
|
+
KeyId: keyId,
|
|
159
|
+
CiphertextBlob: Buffer.from(ciphertext, "base64"),
|
|
160
|
+
...(context ? { EncryptionContext: context } : {}),
|
|
161
|
+
}));
|
|
162
|
+
return {
|
|
163
|
+
plaintext: new Uint8Array(result.Plaintext),
|
|
164
|
+
keyId: result.KeyId ?? keyId,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async sign(keyId, data, algorithm = "RSASSA_PSS_SHA_256") {
|
|
168
|
+
const client = await this.getClient();
|
|
169
|
+
const { SignCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
170
|
+
const result = await client.send(new SignCommand({
|
|
171
|
+
KeyId: keyId,
|
|
172
|
+
Message: data,
|
|
173
|
+
MessageType: "RAW",
|
|
174
|
+
SigningAlgorithm: algorithm,
|
|
175
|
+
}));
|
|
176
|
+
return {
|
|
177
|
+
signature: Buffer.from(result.Signature).toString("base64"),
|
|
178
|
+
keyId: result.KeyId ?? keyId,
|
|
179
|
+
algorithm: result.SigningAlgorithm ?? algorithm,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async verify(keyId, data, signature, algorithm = "RSASSA_PSS_SHA_256") {
|
|
183
|
+
const client = await this.getClient();
|
|
184
|
+
const { VerifyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
185
|
+
const result = await client.send(new VerifyCommand({
|
|
186
|
+
KeyId: keyId,
|
|
187
|
+
Message: data,
|
|
188
|
+
MessageType: "RAW",
|
|
189
|
+
Signature: Buffer.from(signature, "base64"),
|
|
190
|
+
SigningAlgorithm: algorithm,
|
|
191
|
+
}));
|
|
192
|
+
return result.SignatureValid ?? false;
|
|
193
|
+
}
|
|
194
|
+
async rotateKey(keyId) {
|
|
195
|
+
const client = await this.getClient();
|
|
196
|
+
const { EnableKeyRotationCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
197
|
+
await client.send(new EnableKeyRotationCommand({ KeyId: keyId }));
|
|
198
|
+
return this.getKey(keyId);
|
|
199
|
+
}
|
|
200
|
+
async generateDataKey(keyId, keySpec = "AES_256") {
|
|
201
|
+
const client = await this.getClient();
|
|
202
|
+
const { GenerateDataKeyCommand } = await Promise.resolve().then(() => __importStar(require("@aws-sdk/client-kms")));
|
|
203
|
+
const result = await client.send(new GenerateDataKeyCommand({
|
|
204
|
+
KeyId: keyId,
|
|
205
|
+
KeySpec: keySpec,
|
|
206
|
+
}));
|
|
207
|
+
return {
|
|
208
|
+
plaintext: new Uint8Array(result.Plaintext),
|
|
209
|
+
ciphertext: Buffer.from(result.CiphertextBlob).toString("base64"),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.AwsKmsProvider = AwsKmsProvider;
|
|
214
|
+
//# sourceMappingURL=aws.js.map
|