@vaultsandbox/client 0.5.0 → 0.6.0
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/README.md +19 -7
- package/dist/client.d.ts +41 -12
- package/dist/client.js +89 -31
- package/dist/client.js.map +1 -1
- package/dist/crypto/constants.d.ts +52 -3
- package/dist/crypto/constants.js +56 -3
- package/dist/crypto/constants.js.map +1 -1
- package/dist/crypto/decrypt.d.ts +1 -0
- package/dist/crypto/decrypt.js +54 -3
- package/dist/crypto/decrypt.js.map +1 -1
- package/dist/crypto/keypair.d.ts +2 -7
- package/dist/crypto/keypair.js +9 -11
- package/dist/crypto/keypair.js.map +1 -1
- package/dist/crypto/signature.js +2 -2
- package/dist/crypto/signature.js.map +1 -1
- package/dist/crypto/utils.d.ts +1 -0
- package/dist/crypto/utils.js +7 -1
- package/dist/crypto/utils.js.map +1 -1
- package/dist/email.js +9 -9
- package/dist/email.js.map +1 -1
- package/dist/http/api-client.d.ts +2 -1
- package/dist/http/api-client.js +5 -3
- package/dist/http/api-client.js.map +1 -1
- package/dist/inbox.d.ts +9 -3
- package/dist/inbox.js +31 -7
- package/dist/inbox.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/strategies/polling-strategy.js +3 -3
- package/dist/strategies/polling-strategy.js.map +1 -1
- package/dist/strategies/sse-strategy.js +3 -9
- package/dist/strategies/sse-strategy.js.map +1 -1
- package/dist/types/index.d.ts +25 -24
- package/dist/types/index.js.map +1 -1
- package/dist/utils/email-utils.d.ts +1 -1
- package/dist/utils/email-utils.js +7 -8
- package/dist/utils/email-utils.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
<img alt="VaultSandbox" src="./assets/logo-dark.svg">
|
|
5
5
|
</picture>
|
|
6
6
|
|
|
7
|
+
> **VaultSandbox is in Public Beta.** Join the journey to 1.0. Share feedback on [GitHub](https://github.com/vaultsandbox/gateway/discussions).
|
|
8
|
+
|
|
7
9
|
# @vaultsandbox/client
|
|
8
10
|
|
|
9
11
|
[](https://www.npmjs.com/package/@vaultsandbox/client)
|
|
10
12
|
[](https://github.com/vaultsandbox/client-node/actions/workflows/ci.yml)
|
|
13
|
+
[](https://codecov.io/gh/vaultsandbox/client-node)
|
|
11
14
|
[](https://opensource.org/licenses/MIT)
|
|
12
15
|
[](https://nodejs.org/)
|
|
13
16
|
|
|
@@ -122,15 +125,15 @@ if (!validation.passed) {
|
|
|
122
125
|
});
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
// Or check individual results.
|
|
126
|
-
if (email.authResults.spf?.
|
|
127
|
-
expect(email.authResults.spf.
|
|
128
|
+
// Or check individual results. Results can vary based on the sending source.
|
|
129
|
+
if (email.authResults.spf?.result) {
|
|
130
|
+
expect(email.authResults.spf.result).toMatch(/pass|fail|softfail|neutral|temperror|permerror/);
|
|
128
131
|
}
|
|
129
132
|
if (email.authResults.dkim) {
|
|
130
133
|
expect(email.authResults.dkim.length).toBeGreaterThan(0);
|
|
131
134
|
}
|
|
132
|
-
if (email.authResults.dmarc?.
|
|
133
|
-
expect(email.authResults.dmarc.
|
|
135
|
+
if (email.authResults.dmarc?.result) {
|
|
136
|
+
expect(email.authResults.dmarc.result).toMatch(/pass|fail|neutral|temperror|permerror/);
|
|
134
137
|
}
|
|
135
138
|
```
|
|
136
139
|
|
|
@@ -404,6 +407,15 @@ Represents a decrypted email.
|
|
|
404
407
|
- `delete(): Promise<void>` - Deletes this email
|
|
405
408
|
- `getRaw(): Promise<RawEmail>` - Gets raw email source
|
|
406
409
|
|
|
410
|
+
### RawEmail
|
|
411
|
+
|
|
412
|
+
Returned by `email.getRaw()` and `inbox.getRawEmail()`.
|
|
413
|
+
|
|
414
|
+
**Properties:**
|
|
415
|
+
|
|
416
|
+
- `id: string` - Email ID
|
|
417
|
+
- `raw: string` - The raw email source (RFC 5322 format)
|
|
418
|
+
|
|
407
419
|
### AuthResults
|
|
408
420
|
|
|
409
421
|
Returned by `email.authResults`, this object contains email authentication results (SPF, DKIM, DMARC) and a validation helper.
|
|
@@ -598,9 +610,9 @@ All cryptographic operations are performed transparently - developers never need
|
|
|
598
610
|
|
|
599
611
|
## Support
|
|
600
612
|
|
|
601
|
-
- [Documentation](https://vaultsandbox.dev/client-node/
|
|
613
|
+
- [Documentation](https://vaultsandbox.dev/client-node/)
|
|
602
614
|
- [Issue Tracker](https://github.com/vaultsandbox/client-node/issues)
|
|
603
|
-
- [Discussions](https://github.com/vaultsandbox/
|
|
615
|
+
- [Discussions](https://github.com/vaultsandbox/gateway/discussions)
|
|
604
616
|
- [Website](https://www.vaultsandbox.com)
|
|
605
617
|
|
|
606
618
|
## Contributing
|
package/dist/client.d.ts
CHANGED
|
@@ -83,6 +83,13 @@ export declare class VaultSandboxClient {
|
|
|
83
83
|
* @returns A promise that resolves to the number of inboxes deleted.
|
|
84
84
|
*/
|
|
85
85
|
deleteAllInboxes(): Promise<number>;
|
|
86
|
+
/**
|
|
87
|
+
* Deletes a specific inbox by its email address.
|
|
88
|
+
*
|
|
89
|
+
* @param emailAddress - The email address of the inbox to delete.
|
|
90
|
+
* @returns A promise that resolves when the inbox is deleted.
|
|
91
|
+
*/
|
|
92
|
+
deleteInbox(emailAddress: string): Promise<void>;
|
|
86
93
|
/**
|
|
87
94
|
* Retrieves information about the VaultSandbox server.
|
|
88
95
|
*
|
|
@@ -116,6 +123,7 @@ export declare class VaultSandboxClient {
|
|
|
116
123
|
exportInbox(inboxOrEmail: Inbox | string): ExportedInboxData;
|
|
117
124
|
/**
|
|
118
125
|
* Imports an inbox from exported data.
|
|
126
|
+
* See vaultsandbox-spec.md Section 10: Inbox Import Process
|
|
119
127
|
*
|
|
120
128
|
* @param data - The exported inbox data
|
|
121
129
|
* @returns A promise that resolves to the imported Inbox instance
|
|
@@ -125,21 +133,41 @@ export declare class VaultSandboxClient {
|
|
|
125
133
|
* const importedInbox = await client.importInbox(exportedData);
|
|
126
134
|
*/
|
|
127
135
|
importInbox(data: ExportedInboxData): Promise<Inbox>;
|
|
136
|
+
/**
|
|
137
|
+
* Validates the export format version.
|
|
138
|
+
* @private
|
|
139
|
+
* @param data - The exported inbox data to validate
|
|
140
|
+
* @throws {InvalidImportDataError} If version is not supported
|
|
141
|
+
*/
|
|
142
|
+
private validateVersion;
|
|
128
143
|
/**
|
|
129
144
|
* Validates that all required fields are present and non-empty in the exported inbox data.
|
|
130
145
|
* @private
|
|
131
146
|
* @param data - The exported inbox data to validate
|
|
132
|
-
* @throws {InvalidImportDataError} If any required field is missing
|
|
147
|
+
* @throws {InvalidImportDataError} If any required field is missing or empty
|
|
133
148
|
*/
|
|
134
149
|
private validateRequiredFields;
|
|
135
150
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
151
|
+
* Validates that the email address contains exactly one @ character.
|
|
152
|
+
* @private
|
|
153
|
+
* @param emailAddress - The email address to validate
|
|
154
|
+
* @throws {InvalidImportDataError} If email format is invalid
|
|
155
|
+
*/
|
|
156
|
+
private validateEmailAddress;
|
|
157
|
+
/**
|
|
158
|
+
* Validates that the inbox hash is non-empty.
|
|
159
|
+
* @private
|
|
160
|
+
* @param inboxHash - The inbox hash to validate
|
|
161
|
+
* @throws {InvalidImportDataError} If inbox hash is empty
|
|
162
|
+
*/
|
|
163
|
+
private validateInboxHash;
|
|
164
|
+
/**
|
|
165
|
+
* Validates that the server signature public key has the correct size.
|
|
138
166
|
* @private
|
|
139
|
-
* @param
|
|
140
|
-
* @throws {InvalidImportDataError} If
|
|
167
|
+
* @param serverSigPk - The server public key (base64url encoded)
|
|
168
|
+
* @throws {InvalidImportDataError} If server public key has invalid size
|
|
141
169
|
*/
|
|
142
|
-
private
|
|
170
|
+
private validateServerSigPkSize;
|
|
143
171
|
/**
|
|
144
172
|
* Validates that the timestamp fields contain valid ISO 8601 date strings.
|
|
145
173
|
* @private
|
|
@@ -163,22 +191,23 @@ export declare class VaultSandboxClient {
|
|
|
163
191
|
*/
|
|
164
192
|
private validateServerPublicKey;
|
|
165
193
|
/**
|
|
166
|
-
* Decodes the cryptographic keys from
|
|
194
|
+
* Decodes the cryptographic keys from base64url and validates their lengths.
|
|
195
|
+
* Public key is derived from secret key per spec Section 10.2.
|
|
167
196
|
* @private
|
|
168
|
-
* @param data - The exported inbox data containing
|
|
197
|
+
* @param data - The exported inbox data containing base64url-encoded keys
|
|
169
198
|
* @returns A keypair object with decoded keys and base64url-encoded public key
|
|
170
199
|
* @throws {InvalidImportDataError} If keys cannot be decoded or have invalid lengths
|
|
171
200
|
*/
|
|
172
201
|
private decodeAndValidateKeys;
|
|
173
202
|
/**
|
|
174
|
-
* Decodes a
|
|
203
|
+
* Decodes a base64url-encoded cryptographic key to a byte array.
|
|
175
204
|
* @private
|
|
176
|
-
* @param
|
|
205
|
+
* @param keyB64Url - The base64url-encoded key string
|
|
177
206
|
* @param keyType - The type of key (e.g., 'public', 'secret') for error messages
|
|
178
207
|
* @returns The decoded key as a Uint8Array
|
|
179
|
-
* @throws {InvalidImportDataError} If the
|
|
208
|
+
* @throws {InvalidImportDataError} If the base64url string is malformed
|
|
180
209
|
*/
|
|
181
|
-
private
|
|
210
|
+
private decodeBase64UrlKey;
|
|
182
211
|
/**
|
|
183
212
|
* Validates that a cryptographic key has the expected byte length.
|
|
184
213
|
* @private
|
package/dist/client.js
CHANGED
|
@@ -6,8 +6,9 @@ import { readFile, writeFile } from 'fs/promises';
|
|
|
6
6
|
import createDebug from 'debug';
|
|
7
7
|
import { ApiClient } from './http/api-client.js';
|
|
8
8
|
import { Inbox } from './inbox.js';
|
|
9
|
-
import { generateKeypair,
|
|
10
|
-
import { toBase64Url,
|
|
9
|
+
import { generateKeypair, SECRET_KEY_SIZE, derivePublicKeyFromSecret } from './crypto/keypair.js';
|
|
10
|
+
import { toBase64Url, fromBase64Url } from './crypto/utils.js';
|
|
11
|
+
import { EXPORT_VERSION, MLDSA_PUBLIC_KEY_SIZE } from './crypto/constants.js';
|
|
11
12
|
import { SSEStrategy } from './strategies/sse-strategy.js';
|
|
12
13
|
import { PollingStrategy } from './strategies/polling-strategy.js';
|
|
13
14
|
import { InboxNotFoundError, InboxAlreadyExistsError, InvalidImportDataError, StrategyError } from './types/index.js';
|
|
@@ -151,6 +152,16 @@ export class VaultSandboxClient {
|
|
|
151
152
|
this.inboxes.clear();
|
|
152
153
|
return result.deleted;
|
|
153
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Deletes a specific inbox by its email address.
|
|
157
|
+
*
|
|
158
|
+
* @param emailAddress - The email address of the inbox to delete.
|
|
159
|
+
* @returns A promise that resolves when the inbox is deleted.
|
|
160
|
+
*/
|
|
161
|
+
async deleteInbox(emailAddress) {
|
|
162
|
+
await this.apiClient.deleteInbox(emailAddress);
|
|
163
|
+
this.inboxes.delete(emailAddress);
|
|
164
|
+
}
|
|
154
165
|
/**
|
|
155
166
|
* Retrieves information about the VaultSandbox server.
|
|
156
167
|
*
|
|
@@ -209,6 +220,7 @@ export class VaultSandboxClient {
|
|
|
209
220
|
}
|
|
210
221
|
/**
|
|
211
222
|
* Imports an inbox from exported data.
|
|
223
|
+
* See vaultsandbox-spec.md Section 10: Inbox Import Process
|
|
212
224
|
*
|
|
213
225
|
* @param data - The exported inbox data
|
|
214
226
|
* @returns A promise that resolves to the imported Inbox instance
|
|
@@ -218,56 +230,100 @@ export class VaultSandboxClient {
|
|
|
218
230
|
* const importedInbox = await client.importInbox(exportedData);
|
|
219
231
|
*/
|
|
220
232
|
async importInbox(data) {
|
|
233
|
+
// Step 2: Validate version
|
|
234
|
+
this.validateVersion(data);
|
|
235
|
+
// Step 3: Validate required fields
|
|
221
236
|
this.validateRequiredFields(data);
|
|
222
|
-
|
|
237
|
+
// Step 4: Validate emailAddress
|
|
238
|
+
this.validateEmailAddress(data.emailAddress);
|
|
239
|
+
// Step 5: Validate inboxHash
|
|
240
|
+
this.validateInboxHash(data.inboxHash);
|
|
241
|
+
// Step 8: Validate timestamps
|
|
223
242
|
this.validateTimestamps(data);
|
|
243
|
+
// Check for duplicates
|
|
224
244
|
this.checkInboxDoesNotExist(data.emailAddress);
|
|
225
245
|
await this.ensureInitialized();
|
|
246
|
+
// Step 7: Validate and decode serverSigPk
|
|
247
|
+
this.validateServerSigPkSize(data.serverSigPk);
|
|
226
248
|
this.validateServerPublicKey(data.serverSigPk);
|
|
249
|
+
// Step 6: Validate and decode secretKey
|
|
227
250
|
const keypair = this.decodeAndValidateKeys(data);
|
|
228
251
|
const inboxData = this.buildInboxData(data);
|
|
229
252
|
return this.createAndTrackInbox(inboxData, keypair);
|
|
230
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Validates the export format version.
|
|
256
|
+
* @private
|
|
257
|
+
* @param data - The exported inbox data to validate
|
|
258
|
+
* @throws {InvalidImportDataError} If version is not supported
|
|
259
|
+
*/
|
|
260
|
+
validateVersion(data) {
|
|
261
|
+
if (data.version !== EXPORT_VERSION) {
|
|
262
|
+
throw new InvalidImportDataError(`Unsupported version: ${data.version}, expected ${EXPORT_VERSION}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
231
265
|
/**
|
|
232
266
|
* Validates that all required fields are present and non-empty in the exported inbox data.
|
|
233
267
|
* @private
|
|
234
268
|
* @param data - The exported inbox data to validate
|
|
235
|
-
* @throws {InvalidImportDataError} If any required field is missing
|
|
269
|
+
* @throws {InvalidImportDataError} If any required field is missing or empty
|
|
236
270
|
*/
|
|
237
271
|
validateRequiredFields(data) {
|
|
238
|
-
const
|
|
272
|
+
const requiredStringFields = [
|
|
239
273
|
'emailAddress',
|
|
240
274
|
'expiresAt',
|
|
241
275
|
'inboxHash',
|
|
242
276
|
'serverSigPk',
|
|
243
|
-
'
|
|
277
|
+
'secretKey',
|
|
244
278
|
'exportedAt',
|
|
245
279
|
];
|
|
246
|
-
for (const field of
|
|
247
|
-
|
|
280
|
+
for (const field of requiredStringFields) {
|
|
281
|
+
const value = data[field];
|
|
282
|
+
if (value === undefined || value === null || (typeof value === 'string' && value.trim() === '')) {
|
|
248
283
|
throw new InvalidImportDataError(`Missing or invalid field: ${field}`);
|
|
249
284
|
}
|
|
250
285
|
}
|
|
251
286
|
}
|
|
252
287
|
/**
|
|
253
|
-
*
|
|
254
|
-
* In ML-KEM (Kyber), the public key is embedded in the secret key, so we can extract it if missing.
|
|
288
|
+
* Validates that the email address contains exactly one @ character.
|
|
255
289
|
* @private
|
|
256
|
-
* @param
|
|
257
|
-
* @throws {InvalidImportDataError} If
|
|
290
|
+
* @param emailAddress - The email address to validate
|
|
291
|
+
* @throws {InvalidImportDataError} If email format is invalid
|
|
258
292
|
*/
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
293
|
+
validateEmailAddress(emailAddress) {
|
|
294
|
+
const atCount = (emailAddress.match(/@/g) || []).length;
|
|
295
|
+
if (atCount !== 1) {
|
|
296
|
+
throw new InvalidImportDataError('Invalid email address: must contain exactly one @ character');
|
|
262
297
|
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Validates that the inbox hash is non-empty.
|
|
301
|
+
* @private
|
|
302
|
+
* @param inboxHash - The inbox hash to validate
|
|
303
|
+
* @throws {InvalidImportDataError} If inbox hash is empty
|
|
304
|
+
*/
|
|
305
|
+
validateInboxHash(inboxHash) {
|
|
306
|
+
if (!inboxHash || inboxHash.trim() === '') {
|
|
307
|
+
throw new InvalidImportDataError('Invalid inbox hash: must be non-empty');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Validates that the server signature public key has the correct size.
|
|
312
|
+
* @private
|
|
313
|
+
* @param serverSigPk - The server public key (base64url encoded)
|
|
314
|
+
* @throws {InvalidImportDataError} If server public key has invalid size
|
|
315
|
+
*/
|
|
316
|
+
validateServerSigPkSize(serverSigPk) {
|
|
263
317
|
try {
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
318
|
+
const decoded = fromBase64Url(serverSigPk);
|
|
319
|
+
if (decoded.length !== MLDSA_PUBLIC_KEY_SIZE) {
|
|
320
|
+
throw new InvalidImportDataError(`Invalid server public key size: expected ${MLDSA_PUBLIC_KEY_SIZE}, got ${decoded.length}`);
|
|
321
|
+
}
|
|
267
322
|
}
|
|
268
323
|
catch (error) {
|
|
269
|
-
|
|
270
|
-
|
|
324
|
+
if (error instanceof InvalidImportDataError)
|
|
325
|
+
throw error;
|
|
326
|
+
throw new InvalidImportDataError(`Invalid server public key encoding: ${error instanceof Error ? error.message : String(error)}`);
|
|
271
327
|
}
|
|
272
328
|
}
|
|
273
329
|
/**
|
|
@@ -309,17 +365,19 @@ export class VaultSandboxClient {
|
|
|
309
365
|
}
|
|
310
366
|
}
|
|
311
367
|
/**
|
|
312
|
-
* Decodes the cryptographic keys from
|
|
368
|
+
* Decodes the cryptographic keys from base64url and validates their lengths.
|
|
369
|
+
* Public key is derived from secret key per spec Section 10.2.
|
|
313
370
|
* @private
|
|
314
|
-
* @param data - The exported inbox data containing
|
|
371
|
+
* @param data - The exported inbox data containing base64url-encoded keys
|
|
315
372
|
* @returns A keypair object with decoded keys and base64url-encoded public key
|
|
316
373
|
* @throws {InvalidImportDataError} If keys cannot be decoded or have invalid lengths
|
|
317
374
|
*/
|
|
318
375
|
decodeAndValidateKeys(data) {
|
|
319
|
-
|
|
320
|
-
const secretKey = this.
|
|
321
|
-
this.validateKeyLength(publicKey, PUBLIC_KEY_SIZE, 'public');
|
|
376
|
+
// Decode and validate secret key
|
|
377
|
+
const secretKey = this.decodeBase64UrlKey(data.secretKey, 'secret');
|
|
322
378
|
this.validateKeyLength(secretKey, SECRET_KEY_SIZE, 'secret');
|
|
379
|
+
// Derive public key from secret key per spec Section 10.2
|
|
380
|
+
const publicKey = derivePublicKeyFromSecret(secretKey);
|
|
323
381
|
return {
|
|
324
382
|
publicKey,
|
|
325
383
|
secretKey,
|
|
@@ -327,19 +385,19 @@ export class VaultSandboxClient {
|
|
|
327
385
|
};
|
|
328
386
|
}
|
|
329
387
|
/**
|
|
330
|
-
* Decodes a
|
|
388
|
+
* Decodes a base64url-encoded cryptographic key to a byte array.
|
|
331
389
|
* @private
|
|
332
|
-
* @param
|
|
390
|
+
* @param keyB64Url - The base64url-encoded key string
|
|
333
391
|
* @param keyType - The type of key (e.g., 'public', 'secret') for error messages
|
|
334
392
|
* @returns The decoded key as a Uint8Array
|
|
335
|
-
* @throws {InvalidImportDataError} If the
|
|
393
|
+
* @throws {InvalidImportDataError} If the base64url string is malformed
|
|
336
394
|
*/
|
|
337
|
-
|
|
395
|
+
decodeBase64UrlKey(keyB64Url, keyType) {
|
|
338
396
|
try {
|
|
339
|
-
return
|
|
397
|
+
return fromBase64Url(keyB64Url);
|
|
340
398
|
}
|
|
341
399
|
catch {
|
|
342
|
-
throw new InvalidImportDataError(`Invalid
|
|
400
|
+
throw new InvalidImportDataError(`Invalid base64url encoding in ${keyType} key`);
|
|
343
401
|
}
|
|
344
402
|
}
|
|
345
403
|
/**
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,WAAW,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized cryptographic constants for the VaultSandbox client
|
|
3
|
+
* See vaultsandbox-spec.md Appendix B: Size Constants
|
|
3
4
|
*/
|
|
4
5
|
/**
|
|
5
6
|
* HKDF context string used for key derivation
|
|
@@ -7,7 +8,55 @@
|
|
|
7
8
|
*/
|
|
8
9
|
export declare const HKDF_CONTEXT = "vaultsandbox:email:v1";
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
-
* This is the standard size for ML-DSA-65 public keys
|
|
11
|
+
* Algorithm suite identifier string
|
|
12
12
|
*/
|
|
13
|
-
export declare const
|
|
13
|
+
export declare const ALGORITHM_SUITE = "ML-KEM-768:ML-DSA-65:AES-256-GCM:HKDF-SHA-512";
|
|
14
|
+
/**
|
|
15
|
+
* ML-KEM-768 public key size in bytes
|
|
16
|
+
*/
|
|
17
|
+
export declare const MLKEM_PUBLIC_KEY_SIZE = 1184;
|
|
18
|
+
/**
|
|
19
|
+
* ML-KEM-768 secret key size in bytes
|
|
20
|
+
*/
|
|
21
|
+
export declare const MLKEM_SECRET_KEY_SIZE = 2400;
|
|
22
|
+
/**
|
|
23
|
+
* ML-KEM-768 ciphertext size in bytes
|
|
24
|
+
*/
|
|
25
|
+
export declare const MLKEM_CIPHERTEXT_SIZE = 1088;
|
|
26
|
+
/**
|
|
27
|
+
* ML-KEM-768 shared secret size in bytes
|
|
28
|
+
*/
|
|
29
|
+
export declare const MLKEM_SHARED_SECRET_SIZE = 32;
|
|
30
|
+
/**
|
|
31
|
+
* Offset of public key within secret key in bytes
|
|
32
|
+
* The public key is embedded in the secret key at this offset
|
|
33
|
+
*/
|
|
34
|
+
export declare const MLKEM_PUBLIC_KEY_OFFSET = 1152;
|
|
35
|
+
/**
|
|
36
|
+
* ML-DSA-65 public key size in bytes
|
|
37
|
+
*/
|
|
38
|
+
export declare const MLDSA_PUBLIC_KEY_SIZE = 1952;
|
|
39
|
+
/**
|
|
40
|
+
* ML-DSA-65 signature size in bytes
|
|
41
|
+
*/
|
|
42
|
+
export declare const MLDSA_SIGNATURE_SIZE = 3309;
|
|
43
|
+
/**
|
|
44
|
+
* AES-256 key size in bytes
|
|
45
|
+
*/
|
|
46
|
+
export declare const AES_KEY_SIZE = 32;
|
|
47
|
+
/**
|
|
48
|
+
* AES-GCM nonce size in bytes
|
|
49
|
+
*/
|
|
50
|
+
export declare const AES_NONCE_SIZE = 12;
|
|
51
|
+
/**
|
|
52
|
+
* AES-GCM authentication tag size in bytes
|
|
53
|
+
*/
|
|
54
|
+
export declare const AES_TAG_SIZE = 16;
|
|
55
|
+
/**
|
|
56
|
+
* Current export format version
|
|
57
|
+
*/
|
|
58
|
+
export declare const EXPORT_VERSION = 1;
|
|
59
|
+
/**
|
|
60
|
+
* Current protocol version
|
|
61
|
+
*/
|
|
62
|
+
export declare const PROTOCOL_VERSION = 1;
|
package/dist/crypto/constants.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Centralized cryptographic constants for the VaultSandbox client
|
|
3
|
+
* See vaultsandbox-spec.md Appendix B: Size Constants
|
|
3
4
|
*/
|
|
4
5
|
/**
|
|
5
6
|
* HKDF context string used for key derivation
|
|
@@ -7,8 +8,60 @@
|
|
|
7
8
|
*/
|
|
8
9
|
export const HKDF_CONTEXT = 'vaultsandbox:email:v1';
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
-
* This is the standard size for ML-DSA-65 public keys
|
|
11
|
+
* Algorithm suite identifier string
|
|
12
12
|
*/
|
|
13
|
-
export const
|
|
13
|
+
export const ALGORITHM_SUITE = 'ML-KEM-768:ML-DSA-65:AES-256-GCM:HKDF-SHA-512';
|
|
14
|
+
// ===== ML-KEM-768 Constants =====
|
|
15
|
+
/**
|
|
16
|
+
* ML-KEM-768 public key size in bytes
|
|
17
|
+
*/
|
|
18
|
+
export const MLKEM_PUBLIC_KEY_SIZE = 1184;
|
|
19
|
+
/**
|
|
20
|
+
* ML-KEM-768 secret key size in bytes
|
|
21
|
+
*/
|
|
22
|
+
export const MLKEM_SECRET_KEY_SIZE = 2400;
|
|
23
|
+
/**
|
|
24
|
+
* ML-KEM-768 ciphertext size in bytes
|
|
25
|
+
*/
|
|
26
|
+
export const MLKEM_CIPHERTEXT_SIZE = 1088;
|
|
27
|
+
/**
|
|
28
|
+
* ML-KEM-768 shared secret size in bytes
|
|
29
|
+
*/
|
|
30
|
+
export const MLKEM_SHARED_SECRET_SIZE = 32;
|
|
31
|
+
/**
|
|
32
|
+
* Offset of public key within secret key in bytes
|
|
33
|
+
* The public key is embedded in the secret key at this offset
|
|
34
|
+
*/
|
|
35
|
+
export const MLKEM_PUBLIC_KEY_OFFSET = 1152;
|
|
36
|
+
// ===== ML-DSA-65 Constants =====
|
|
37
|
+
/**
|
|
38
|
+
* ML-DSA-65 public key size in bytes
|
|
39
|
+
*/
|
|
40
|
+
export const MLDSA_PUBLIC_KEY_SIZE = 1952;
|
|
41
|
+
/**
|
|
42
|
+
* ML-DSA-65 signature size in bytes
|
|
43
|
+
*/
|
|
44
|
+
export const MLDSA_SIGNATURE_SIZE = 3309;
|
|
45
|
+
// ===== AES-256-GCM Constants =====
|
|
46
|
+
/**
|
|
47
|
+
* AES-256 key size in bytes
|
|
48
|
+
*/
|
|
49
|
+
export const AES_KEY_SIZE = 32;
|
|
50
|
+
/**
|
|
51
|
+
* AES-GCM nonce size in bytes
|
|
52
|
+
*/
|
|
53
|
+
export const AES_NONCE_SIZE = 12;
|
|
54
|
+
/**
|
|
55
|
+
* AES-GCM authentication tag size in bytes
|
|
56
|
+
*/
|
|
57
|
+
export const AES_TAG_SIZE = 16;
|
|
58
|
+
// ===== Export Format Constants =====
|
|
59
|
+
/**
|
|
60
|
+
* Current export format version
|
|
61
|
+
*/
|
|
62
|
+
export const EXPORT_VERSION = 1;
|
|
63
|
+
/**
|
|
64
|
+
* Current protocol version
|
|
65
|
+
*/
|
|
66
|
+
export const PROTOCOL_VERSION = 1;
|
|
14
67
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/crypto/constants.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/crypto/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAEpD;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,+CAA+C,CAAC;AAE/E,mCAAmC;AAEnC;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,oCAAoC;AAEpC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B,sCAAsC;AAEtC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEhC;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC"}
|
package/dist/crypto/decrypt.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { Keypair, EncryptedData } from '../types/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Decrypts an encrypted payload using the complete reference implementation flow
|
|
8
|
+
* See vaultsandbox-spec.md Section 8: Decryption Process
|
|
8
9
|
*
|
|
9
10
|
* @param encryptedData - The encrypted data from the server
|
|
10
11
|
* @param keypair - The recipient's keypair
|
package/dist/crypto/decrypt.js
CHANGED
|
@@ -7,9 +7,58 @@ import { fromBase64Url, ensureOwnBuffer, fromBase64 } from './utils.js';
|
|
|
7
7
|
import { DecryptionError, SignatureVerificationError } from '../types/index.js';
|
|
8
8
|
import { verifySignature } from './signature.js';
|
|
9
9
|
import { deriveKey } from './keypair.js';
|
|
10
|
-
import { HKDF_CONTEXT } from './constants.js';
|
|
10
|
+
import { HKDF_CONTEXT, PROTOCOL_VERSION, MLKEM_CIPHERTEXT_SIZE, AES_NONCE_SIZE, MLDSA_SIGNATURE_SIZE, MLDSA_PUBLIC_KEY_SIZE, } from './constants.js';
|
|
11
|
+
/**
|
|
12
|
+
* Validates the encrypted payload structure and sizes per spec Section 8.1
|
|
13
|
+
* @throws DecryptionError if validation fails
|
|
14
|
+
*/
|
|
15
|
+
function validatePayload(encryptedData) {
|
|
16
|
+
// Step 2: Validate version
|
|
17
|
+
if (encryptedData.v !== PROTOCOL_VERSION) {
|
|
18
|
+
throw new DecryptionError(`Unsupported protocol version: ${encryptedData.v}, expected ${PROTOCOL_VERSION}`);
|
|
19
|
+
}
|
|
20
|
+
// Step 3: Validate algorithms
|
|
21
|
+
const { algs } = encryptedData;
|
|
22
|
+
if (algs.kem !== 'ML-KEM-768') {
|
|
23
|
+
throw new DecryptionError(`Unsupported KEM algorithm: ${algs.kem}`);
|
|
24
|
+
}
|
|
25
|
+
if (algs.sig !== 'ML-DSA-65') {
|
|
26
|
+
throw new DecryptionError(`Unsupported signature algorithm: ${algs.sig}`);
|
|
27
|
+
}
|
|
28
|
+
if (algs.aead !== 'AES-256-GCM') {
|
|
29
|
+
throw new DecryptionError(`Unsupported AEAD algorithm: ${algs.aead}`);
|
|
30
|
+
}
|
|
31
|
+
if (algs.kdf !== 'HKDF-SHA-512') {
|
|
32
|
+
throw new DecryptionError(`Unsupported KDF algorithm: ${algs.kdf}`);
|
|
33
|
+
}
|
|
34
|
+
// Step 4: Validate decoded sizes (decode first, then check)
|
|
35
|
+
try {
|
|
36
|
+
const ctKem = fromBase64Url(encryptedData.ct_kem);
|
|
37
|
+
if (ctKem.length !== MLKEM_CIPHERTEXT_SIZE) {
|
|
38
|
+
throw new DecryptionError(`Invalid ct_kem size: expected ${MLKEM_CIPHERTEXT_SIZE}, got ${ctKem.length}`);
|
|
39
|
+
}
|
|
40
|
+
const nonce = fromBase64Url(encryptedData.nonce);
|
|
41
|
+
if (nonce.length !== AES_NONCE_SIZE) {
|
|
42
|
+
throw new DecryptionError(`Invalid nonce size: expected ${AES_NONCE_SIZE}, got ${nonce.length}`);
|
|
43
|
+
}
|
|
44
|
+
const sig = fromBase64Url(encryptedData.sig);
|
|
45
|
+
if (sig.length !== MLDSA_SIGNATURE_SIZE) {
|
|
46
|
+
throw new DecryptionError(`Invalid signature size: expected ${MLDSA_SIGNATURE_SIZE}, got ${sig.length}`);
|
|
47
|
+
}
|
|
48
|
+
const serverSigPk = fromBase64Url(encryptedData.server_sig_pk);
|
|
49
|
+
if (serverSigPk.length !== MLDSA_PUBLIC_KEY_SIZE) {
|
|
50
|
+
throw new DecryptionError(`Invalid server public key size: expected ${MLDSA_PUBLIC_KEY_SIZE}, got ${serverSigPk.length}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof DecryptionError)
|
|
55
|
+
throw error;
|
|
56
|
+
throw new DecryptionError(`Failed to decode payload: ${error instanceof Error ? error.message : String(error)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
11
59
|
/**
|
|
12
60
|
* Decrypts an encrypted payload using the complete reference implementation flow
|
|
61
|
+
* See vaultsandbox-spec.md Section 8: Decryption Process
|
|
13
62
|
*
|
|
14
63
|
* @param encryptedData - The encrypted data from the server
|
|
15
64
|
* @param keypair - The recipient's keypair
|
|
@@ -18,9 +67,11 @@ import { HKDF_CONTEXT } from './constants.js';
|
|
|
18
67
|
*/
|
|
19
68
|
export async function decrypt(encryptedData, keypair) {
|
|
20
69
|
try {
|
|
21
|
-
//
|
|
70
|
+
// Steps 1-4: Parse and validate payload (version, algorithms, sizes)
|
|
71
|
+
validatePayload(encryptedData);
|
|
72
|
+
// Step 6: SECURITY: Verify signature BEFORE decryption (prevent tampering)
|
|
22
73
|
verifySignature(encryptedData);
|
|
23
|
-
//
|
|
74
|
+
// Step 7-9: Decode, decapsulate, derive key, decrypt
|
|
24
75
|
const ctKem = fromBase64Url(encryptedData.ct_kem);
|
|
25
76
|
const nonceBytes = fromBase64Url(encryptedData.nonce);
|
|
26
77
|
const aadBytes = fromBase64Url(encryptedData.aad);
|