@de-otio/chaoskb-client 0.3.6 → 0.3.8
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/dist/cli/bootstrap.d.ts +11 -3
- package/dist/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +181 -126
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/commands/config.d.ts +30 -4
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +289 -134
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/devices.d.ts.map +1 -1
- package/dist/cli/commands/devices.js +58 -33
- package/dist/cli/commands/devices.js.map +1 -1
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +6 -9
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/import.js +1 -1
- package/dist/cli/commands/import.js.map +1 -1
- package/dist/cli/commands/projects.d.ts.map +1 -1
- package/dist/cli/commands/projects.js +33 -10
- package/dist/cli/commands/projects.js.map +1 -1
- package/dist/cli/commands/rotate-key.d.ts +3 -3
- package/dist/cli/commands/rotate-key.d.ts.map +1 -1
- package/dist/cli/commands/rotate-key.js +88 -35
- package/dist/cli/commands/rotate-key.js.map +1 -1
- package/dist/cli/commands/setup-sync.d.ts.map +1 -1
- package/dist/cli/commands/setup-sync.js +22 -4
- package/dist/cli/commands/setup-sync.js.map +1 -1
- package/dist/cli/index.js +20 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-server.d.ts +6 -0
- package/dist/cli/mcp-server.d.ts.map +1 -1
- package/dist/cli/mcp-server.js +93 -42
- package/dist/cli/mcp-server.js.map +1 -1
- package/dist/crypto/aad.d.ts +2 -5
- package/dist/crypto/aad.d.ts.map +1 -1
- package/dist/crypto/aad.js +2 -8
- package/dist/crypto/aad.js.map +1 -1
- package/dist/crypto/aead.d.ts +8 -16
- package/dist/crypto/aead.d.ts.map +1 -1
- package/dist/crypto/aead.js +10 -36
- package/dist/crypto/aead.js.map +1 -1
- package/dist/crypto/blob-id.d.ts +2 -3
- package/dist/crypto/blob-id.d.ts.map +1 -1
- package/dist/crypto/blob-id.js +2 -30
- package/dist/crypto/blob-id.js.map +1 -1
- package/dist/crypto/canonical-json.d.ts +5 -3
- package/dist/crypto/canonical-json.d.ts.map +1 -1
- package/dist/crypto/canonical-json.js +5 -85
- package/dist/crypto/canonical-json.js.map +1 -1
- package/dist/crypto/commitment.d.ts +3 -9
- package/dist/crypto/commitment.d.ts.map +1 -1
- package/dist/crypto/commitment.js +3 -27
- package/dist/crypto/commitment.js.map +1 -1
- package/dist/crypto/encryption-service.d.ts +3 -0
- package/dist/crypto/encryption-service.d.ts.map +1 -1
- package/dist/crypto/encryption-service.js +10 -6
- package/dist/crypto/encryption-service.js.map +1 -1
- package/dist/crypto/envelope-cbor.d.ts +4 -34
- package/dist/crypto/envelope-cbor.d.ts.map +1 -1
- package/dist/crypto/envelope-cbor.js +4 -121
- package/dist/crypto/envelope-cbor.js.map +1 -1
- package/dist/crypto/envelope.d.ts +1 -31
- package/dist/crypto/envelope.d.ts.map +1 -1
- package/dist/crypto/envelope.js +31 -137
- package/dist/crypto/envelope.js.map +1 -1
- package/dist/crypto/hkdf.d.ts +7 -11
- package/dist/crypto/hkdf.d.ts.map +1 -1
- package/dist/crypto/hkdf.js +9 -18
- package/dist/crypto/hkdf.js.map +1 -1
- package/dist/crypto/index.d.ts +9 -4
- package/dist/crypto/index.d.ts.map +1 -1
- package/dist/crypto/index.js +9 -4
- package/dist/crypto/index.js.map +1 -1
- package/dist/crypto/ssh-keys.d.ts +17 -10
- package/dist/crypto/ssh-keys.d.ts.map +1 -1
- package/dist/crypto/ssh-keys.js +28 -108
- package/dist/crypto/ssh-keys.js.map +1 -1
- package/dist/crypto/types.d.ts +18 -88
- package/dist/crypto/types.d.ts.map +1 -1
- package/dist/crypto/types.js +3 -0
- package/dist/crypto/types.js.map +1 -1
- package/dist/pipeline/content-pipeline.d.ts.map +1 -1
- package/dist/pipeline/content-pipeline.js +21 -5
- package/dist/pipeline/content-pipeline.js.map +1 -1
- package/dist/pipeline/extract.d.ts +8 -0
- package/dist/pipeline/extract.d.ts.map +1 -1
- package/dist/pipeline/extract.js +15 -4
- package/dist/pipeline/extract.js.map +1 -1
- package/dist/pipeline/fetch-browser.d.ts +29 -0
- package/dist/pipeline/fetch-browser.d.ts.map +1 -0
- package/dist/pipeline/fetch-browser.js +98 -0
- package/dist/pipeline/fetch-browser.js.map +1 -0
- package/dist/pipeline/safety.d.ts +43 -6
- package/dist/pipeline/safety.d.ts.map +1 -1
- package/dist/pipeline/safety.js +52 -15
- package/dist/pipeline/safety.js.map +1 -1
- package/dist/pipeline/validate.js +35 -23
- package/dist/pipeline/validate.js.map +1 -1
- package/package.json +4 -1
- package/dist/crypto/argon2.d.ts +0 -11
- package/dist/crypto/argon2.d.ts.map +0 -1
- package/dist/crypto/argon2.js +0 -33
- package/dist/crypto/argon2.js.map +0 -1
- package/dist/crypto/invite.d.ts +0 -31
- package/dist/crypto/invite.d.ts.map +0 -1
- package/dist/crypto/invite.js +0 -139
- package/dist/crypto/invite.js.map +0 -1
- package/dist/crypto/keyring.d.ts +0 -37
- package/dist/crypto/keyring.d.ts.map +0 -1
- package/dist/crypto/keyring.js +0 -219
- package/dist/crypto/keyring.js.map +0 -1
- package/dist/crypto/known-keys.d.ts +0 -34
- package/dist/crypto/known-keys.d.ts.map +0 -1
- package/dist/crypto/known-keys.js +0 -114
- package/dist/crypto/known-keys.js.map +0 -1
- package/dist/crypto/project-keys.d.ts +0 -26
- package/dist/crypto/project-keys.d.ts.map +0 -1
- package/dist/crypto/project-keys.js +0 -69
- package/dist/crypto/project-keys.js.map +0 -1
- package/dist/crypto/secure-buffer.d.ts +0 -31
- package/dist/crypto/secure-buffer.d.ts.map +0 -1
- package/dist/crypto/secure-buffer.js +0 -61
- package/dist/crypto/secure-buffer.js.map +0 -1
- package/dist/crypto/tiers/enhanced.d.ts +0 -25
- package/dist/crypto/tiers/enhanced.d.ts.map +0 -1
- package/dist/crypto/tiers/enhanced.js +0 -56
- package/dist/crypto/tiers/enhanced.js.map +0 -1
- package/dist/crypto/tiers/maximum.d.ts +0 -19
- package/dist/crypto/tiers/maximum.d.ts.map +0 -1
- package/dist/crypto/tiers/maximum.js +0 -25
- package/dist/crypto/tiers/maximum.js.map +0 -1
- package/dist/crypto/tiers/standard.d.ts +0 -27
- package/dist/crypto/tiers/standard.d.ts.map +0 -1
- package/dist/crypto/tiers/standard.js +0 -155
- package/dist/crypto/tiers/standard.js.map +0 -1
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
// Enhanced tier removed — see doc/analysis/zero-config-sync/security-tiers.md
|
|
2
|
-
// This file is deprecated. The zero-config sync implementation uses only two tiers:
|
|
3
|
-
// - Standard: SSH key wrapping (automatic, zero-config)
|
|
4
|
-
// - Maximum: Argon2id passphrase derivation
|
|
5
|
-
// The Enhanced (BIP39 mnemonic) tier added complexity without meaningful security
|
|
6
|
-
// benefit over the Standard tier's SSH-based recovery. Retained for backward
|
|
7
|
-
// compatibility with existing Enhanced-tier users.
|
|
8
|
-
import * as bip39 from 'bip39';
|
|
9
|
-
import { SecureBuffer } from '../secure-buffer.js';
|
|
10
|
-
// Re-export standard tier wrapping for dual-path recovery
|
|
11
|
-
export { wrapMasterKey, unwrapMasterKeyEd25519, unwrapMasterKeyRSA } from './standard.js';
|
|
12
|
-
/**
|
|
13
|
-
* @deprecated Enhanced tier is deprecated. New installations use Standard or Maximum only.
|
|
14
|
-
*
|
|
15
|
-
* Enhanced tier: BIP39 24-word recovery key.
|
|
16
|
-
*
|
|
17
|
-
* The master key is a 256-bit random value which maps directly to a 24-word
|
|
18
|
-
* BIP39 mnemonic. Either the mnemonic or the SSH-wrapped key can recover.
|
|
19
|
-
*/
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated Use Standard tier (SSH key wrapping) instead.
|
|
22
|
-
*
|
|
23
|
-
* Encode a 256-bit master key as a 24-word BIP39 mnemonic.
|
|
24
|
-
* The master key bytes are used directly as the entropy.
|
|
25
|
-
*/
|
|
26
|
-
export function generateRecoveryKey(masterKey) {
|
|
27
|
-
if (masterKey.length !== 32) {
|
|
28
|
-
throw new Error(`Master key must be 32 bytes (256 bits), got ${masterKey.length}`);
|
|
29
|
-
}
|
|
30
|
-
const entropy = Buffer.from(masterKey.buffer).toString('hex');
|
|
31
|
-
const mnemonic = bip39.entropyToMnemonic(entropy);
|
|
32
|
-
return mnemonic;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* @deprecated Use Standard tier (SSH key wrapping) instead.
|
|
36
|
-
*
|
|
37
|
-
* Decode a 24-word BIP39 mnemonic back to the 256-bit master key.
|
|
38
|
-
* Returns a SecureBuffer containing the recovered key.
|
|
39
|
-
*/
|
|
40
|
-
export function recoverFromMnemonic(mnemonic) {
|
|
41
|
-
const trimmed = mnemonic.trim().toLowerCase();
|
|
42
|
-
if (!bip39.validateMnemonic(trimmed)) {
|
|
43
|
-
throw new Error('Invalid BIP39 mnemonic');
|
|
44
|
-
}
|
|
45
|
-
const words = trimmed.split(/\s+/);
|
|
46
|
-
if (words.length !== 24) {
|
|
47
|
-
throw new Error(`Expected 24-word mnemonic, got ${words.length} words`);
|
|
48
|
-
}
|
|
49
|
-
const entropyHex = bip39.mnemonicToEntropy(trimmed);
|
|
50
|
-
const entropyBytes = Buffer.from(entropyHex, 'hex');
|
|
51
|
-
if (entropyBytes.length !== 32) {
|
|
52
|
-
throw new Error(`Recovered entropy must be 32 bytes, got ${entropyBytes.length}`);
|
|
53
|
-
}
|
|
54
|
-
return SecureBuffer.from(entropyBytes);
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=enhanced.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"enhanced.js","sourceRoot":"","sources":["../../../crypto/tiers/enhanced.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,oFAAoF;AACpF,0DAA0D;AAC1D,8CAA8C;AAC9C,kFAAkF;AAClF,6EAA6E;AAC7E,mDAAmD;AAEnD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,0DAA0D;AAC1D,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAE1F;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,SAAwB;IAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,+CAA+C,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,kCAAkC,KAAK,CAAC,MAAM,QAAQ,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAEpD,IAAI,YAAY,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,2CAA2C,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ISecureBuffer } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Maximum tier: Argon2id passphrase derivation.
|
|
4
|
-
*
|
|
5
|
-
* The master key is derived from a user-chosen passphrase.
|
|
6
|
-
* No recovery path — if the passphrase is lost, data is lost.
|
|
7
|
-
*/
|
|
8
|
-
/**
|
|
9
|
-
* Derive a master key from a passphrase using Argon2id.
|
|
10
|
-
*
|
|
11
|
-
* @param passphrase - User passphrase
|
|
12
|
-
* @param salt - Optional 16-byte salt. If not provided, a random one is generated.
|
|
13
|
-
* @returns Object with the derived master key and the salt (for server storage)
|
|
14
|
-
*/
|
|
15
|
-
export declare function deriveFromPassphrase(passphrase: string, salt?: Uint8Array): {
|
|
16
|
-
masterKey: ISecureBuffer;
|
|
17
|
-
salt: Uint8Array;
|
|
18
|
-
};
|
|
19
|
-
//# sourceMappingURL=maximum.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maximum.d.ts","sourceRoot":"","sources":["../../../crypto/tiers/maximum.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD;;;;;GAKG;AAEH;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,UAAU,GAChB;IAAE,SAAS,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAUhD"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from 'node:crypto';
|
|
2
|
-
import { deriveFromPassphrase as argon2Derive } from '../argon2.js';
|
|
3
|
-
const SALT_LENGTH = 16;
|
|
4
|
-
/**
|
|
5
|
-
* Maximum tier: Argon2id passphrase derivation.
|
|
6
|
-
*
|
|
7
|
-
* The master key is derived from a user-chosen passphrase.
|
|
8
|
-
* No recovery path — if the passphrase is lost, data is lost.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Derive a master key from a passphrase using Argon2id.
|
|
12
|
-
*
|
|
13
|
-
* @param passphrase - User passphrase
|
|
14
|
-
* @param salt - Optional 16-byte salt. If not provided, a random one is generated.
|
|
15
|
-
* @returns Object with the derived master key and the salt (for server storage)
|
|
16
|
-
*/
|
|
17
|
-
export function deriveFromPassphrase(passphrase, salt) {
|
|
18
|
-
const actualSalt = salt ?? new Uint8Array(randomBytes(SALT_LENGTH));
|
|
19
|
-
if (actualSalt.length !== SALT_LENGTH) {
|
|
20
|
-
throw new Error(`Salt must be ${SALT_LENGTH} bytes, got ${actualSalt.length}`);
|
|
21
|
-
}
|
|
22
|
-
const masterKey = argon2Derive(passphrase, actualSalt);
|
|
23
|
-
return { masterKey, salt: actualSalt };
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=maximum.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maximum.js","sourceRoot":"","sources":["../../../crypto/tiers/maximum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,oBAAoB,IAAI,YAAY,EAAE,MAAM,cAAc,CAAC;AAGpE,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;;GAKG;AAEH;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,UAAkB,EAClB,IAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,IAAI,IAAI,UAAU,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC;IAEpE,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,gBAAgB,WAAW,eAAe,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAEvD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import * as crypto from 'node:crypto';
|
|
2
|
-
import type { ISecureBuffer, SSHKeyInfo } from '../types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Standard tier: SSH key wrapping.
|
|
5
|
-
*
|
|
6
|
-
* For Ed25519 keys: crypto_box_seal (ephemeral X25519 ECDH + XSalsa20-Poly1305)
|
|
7
|
-
* For RSA keys: RSA-OAEP-SHA256 KEM + XChaCha20-Poly1305 DEM
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Wrap a master key with an SSH public key.
|
|
11
|
-
* Ed25519: uses crypto_box_seal after converting to X25519.
|
|
12
|
-
* RSA: uses RSA-OAEP KEM + XChaCha20-Poly1305 DEM.
|
|
13
|
-
*/
|
|
14
|
-
export declare function wrapMasterKey(masterKey: ISecureBuffer, sshPublicKey: SSHKeyInfo): Uint8Array;
|
|
15
|
-
/**
|
|
16
|
-
* Unwrap a master key with an SSH private key (Ed25519).
|
|
17
|
-
* @param wrappedKey - The sealed box
|
|
18
|
-
* @param ed25519SecretKey - The 64-byte Ed25519 secret key
|
|
19
|
-
*/
|
|
20
|
-
export declare function unwrapMasterKeyEd25519(wrappedKey: Uint8Array, ed25519SecretKey: Uint8Array, ed25519PublicKey: Uint8Array): ISecureBuffer;
|
|
21
|
-
/**
|
|
22
|
-
* Unwrap a master key wrapped with RSA-OAEP KEM + DEM.
|
|
23
|
-
* @param wrappedKey - Serialized [4-byte wrappedWKLen][wrappedWK][nonce][ct][tag]
|
|
24
|
-
* @param rsaPrivateKey - RSA private key in PEM or DER format
|
|
25
|
-
*/
|
|
26
|
-
export declare function unwrapMasterKeyRSA(wrappedKey: Uint8Array, rsaPrivateKey: crypto.KeyObject): ISecureBuffer;
|
|
27
|
-
//# sourceMappingURL=standard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"standard.d.ts","sourceRoot":"","sources":["../../../crypto/tiers/standard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAMtC,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI7D;;;;;GAKG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,GAAG,UAAU,CAO5F;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,UAAU,EACtB,gBAAgB,EAAE,UAAU,EAC5B,gBAAgB,EAAE,UAAU,GAC3B,aAAa,CAmBf;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,CAAC,SAAS,GAC9B,aAAa,CA0Cf"}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import * as crypto from 'node:crypto';
|
|
2
|
-
import sodium from 'sodium-native';
|
|
3
|
-
import { aeadEncrypt, aeadDecrypt } from '../aead.js';
|
|
4
|
-
import { SecureBuffer } from '../secure-buffer.js';
|
|
5
|
-
import { ed25519ToX25519PublicKey, ed25519ToX25519SecretKey } from '../ssh-keys.js';
|
|
6
|
-
const RSA_MIN_BITS = 2048;
|
|
7
|
-
/**
|
|
8
|
-
* Standard tier: SSH key wrapping.
|
|
9
|
-
*
|
|
10
|
-
* For Ed25519 keys: crypto_box_seal (ephemeral X25519 ECDH + XSalsa20-Poly1305)
|
|
11
|
-
* For RSA keys: RSA-OAEP-SHA256 KEM + XChaCha20-Poly1305 DEM
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Wrap a master key with an SSH public key.
|
|
15
|
-
* Ed25519: uses crypto_box_seal after converting to X25519.
|
|
16
|
-
* RSA: uses RSA-OAEP KEM + XChaCha20-Poly1305 DEM.
|
|
17
|
-
*/
|
|
18
|
-
export function wrapMasterKey(masterKey, sshPublicKey) {
|
|
19
|
-
if (sshPublicKey.type === 'ed25519') {
|
|
20
|
-
return wrapWithEd25519(masterKey, sshPublicKey.publicKeyBytes);
|
|
21
|
-
}
|
|
22
|
-
else if (sshPublicKey.type === 'rsa') {
|
|
23
|
-
return wrapWithRSA(masterKey, sshPublicKey.publicKeyBytes);
|
|
24
|
-
}
|
|
25
|
-
throw new Error(`Unsupported SSH key type: ${sshPublicKey.type}`);
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Unwrap a master key with an SSH private key (Ed25519).
|
|
29
|
-
* @param wrappedKey - The sealed box
|
|
30
|
-
* @param ed25519SecretKey - The 64-byte Ed25519 secret key
|
|
31
|
-
*/
|
|
32
|
-
export function unwrapMasterKeyEd25519(wrappedKey, ed25519SecretKey, ed25519PublicKey) {
|
|
33
|
-
const x25519Sk = ed25519ToX25519SecretKey(ed25519SecretKey);
|
|
34
|
-
const x25519Pk = ed25519ToX25519PublicKey(ed25519PublicKey);
|
|
35
|
-
const skBuf = Buffer.from(x25519Sk);
|
|
36
|
-
const pkBuf = Buffer.from(x25519Pk);
|
|
37
|
-
const plaintext = Buffer.alloc(wrappedKey.length - sodium.crypto_box_SEALBYTES);
|
|
38
|
-
try {
|
|
39
|
-
sodium.crypto_box_seal_open(plaintext, Buffer.from(wrappedKey), pkBuf, skBuf);
|
|
40
|
-
return SecureBuffer.from(plaintext);
|
|
41
|
-
}
|
|
42
|
-
finally {
|
|
43
|
-
sodium.sodium_memzero(skBuf);
|
|
44
|
-
sodium.sodium_memzero(pkBuf);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Unwrap a master key wrapped with RSA-OAEP KEM + DEM.
|
|
49
|
-
* @param wrappedKey - Serialized [4-byte wrappedWKLen][wrappedWK][nonce][ct][tag]
|
|
50
|
-
* @param rsaPrivateKey - RSA private key in PEM or DER format
|
|
51
|
-
*/
|
|
52
|
-
export function unwrapMasterKeyRSA(wrappedKey, rsaPrivateKey) {
|
|
53
|
-
const buf = Buffer.from(wrappedKey);
|
|
54
|
-
let offset = 0;
|
|
55
|
-
// Read wrapped wrapping key length
|
|
56
|
-
const wrappedWKLen = buf.readUInt32BE(offset);
|
|
57
|
-
offset += 4;
|
|
58
|
-
// Read wrapped wrapping key
|
|
59
|
-
const wrappedWK = buf.subarray(offset, offset + wrappedWKLen);
|
|
60
|
-
offset += wrappedWKLen;
|
|
61
|
-
// Remaining is AEAD encrypted master key: nonce(24) || ciphertext || tag(16)
|
|
62
|
-
const aeadPayload = buf.subarray(offset);
|
|
63
|
-
const nonce = aeadPayload.subarray(0, 24);
|
|
64
|
-
const ciphertext = aeadPayload.subarray(24, aeadPayload.length - 16);
|
|
65
|
-
const tag = aeadPayload.subarray(aeadPayload.length - 16);
|
|
66
|
-
// Decrypt wrapping key with RSA-OAEP
|
|
67
|
-
const wrappingKey = crypto.privateDecrypt({
|
|
68
|
-
key: rsaPrivateKey,
|
|
69
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
70
|
-
oaepHash: 'sha256',
|
|
71
|
-
}, wrappedWK);
|
|
72
|
-
// Decrypt master key with XChaCha20-Poly1305
|
|
73
|
-
const emptyAAD = new Uint8Array(0);
|
|
74
|
-
const masterKeyBytes = aeadDecrypt(new Uint8Array(wrappingKey), new Uint8Array(nonce), new Uint8Array(ciphertext), new Uint8Array(tag), emptyAAD);
|
|
75
|
-
// Zero the wrapping key
|
|
76
|
-
wrappingKey.fill(0);
|
|
77
|
-
return SecureBuffer.from(Buffer.from(masterKeyBytes));
|
|
78
|
-
}
|
|
79
|
-
// --- Internal helpers ---
|
|
80
|
-
function wrapWithEd25519(masterKey, ed25519PublicKey) {
|
|
81
|
-
const x25519Pk = ed25519ToX25519PublicKey(ed25519PublicKey);
|
|
82
|
-
const sealed = Buffer.alloc(masterKey.length + sodium.crypto_box_SEALBYTES);
|
|
83
|
-
sodium.crypto_box_seal(sealed, masterKey.buffer, Buffer.from(x25519Pk));
|
|
84
|
-
return new Uint8Array(sealed);
|
|
85
|
-
}
|
|
86
|
-
function wrapWithRSA(masterKey, rsaPublicKeyBytes) {
|
|
87
|
-
// Parse the RSA public key bytes (SSH wire format: exponent + modulus)
|
|
88
|
-
const rsaPubKey = rsaPublicKeyBytesToKeyObject(rsaPublicKeyBytes);
|
|
89
|
-
// Check minimum key size
|
|
90
|
-
const keyDetail = rsaPubKey.asymmetricKeySize;
|
|
91
|
-
if (keyDetail !== undefined && keyDetail * 8 < RSA_MIN_BITS) {
|
|
92
|
-
throw new Error(`RSA key too small: ${keyDetail * 8} bits (minimum ${RSA_MIN_BITS})`);
|
|
93
|
-
}
|
|
94
|
-
// Generate random 32-byte wrapping key
|
|
95
|
-
const wrappingKey = crypto.randomBytes(32);
|
|
96
|
-
// RSA-OAEP encrypt the wrapping key
|
|
97
|
-
const wrappedWK = crypto.publicEncrypt({
|
|
98
|
-
key: rsaPubKey,
|
|
99
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
100
|
-
oaepHash: 'sha256',
|
|
101
|
-
}, wrappingKey);
|
|
102
|
-
// XChaCha20-Poly1305 encrypt the master key with the wrapping key
|
|
103
|
-
const emptyAAD = new Uint8Array(0);
|
|
104
|
-
const { nonce, ciphertext, tag } = aeadEncrypt(new Uint8Array(wrappingKey), new Uint8Array(masterKey.buffer), emptyAAD);
|
|
105
|
-
// Zero the wrapping key
|
|
106
|
-
wrappingKey.fill(0);
|
|
107
|
-
// Serialize: [4-byte wrappedWK length][wrappedWK][nonce][ciphertext][tag]
|
|
108
|
-
const totalLen = 4 + wrappedWK.length + nonce.length + ciphertext.length + tag.length;
|
|
109
|
-
const result = Buffer.alloc(totalLen);
|
|
110
|
-
let offset = 0;
|
|
111
|
-
result.writeUInt32BE(wrappedWK.length, offset);
|
|
112
|
-
offset += 4;
|
|
113
|
-
wrappedWK.copy(result, offset);
|
|
114
|
-
offset += wrappedWK.length;
|
|
115
|
-
Buffer.from(nonce).copy(result, offset);
|
|
116
|
-
offset += nonce.length;
|
|
117
|
-
Buffer.from(ciphertext).copy(result, offset);
|
|
118
|
-
offset += ciphertext.length;
|
|
119
|
-
Buffer.from(tag).copy(result, offset);
|
|
120
|
-
return new Uint8Array(result);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Convert SSH wire format RSA public key bytes to a Node.js KeyObject.
|
|
124
|
-
* Input: [4-byte exponent length][exponent][4-byte modulus length][modulus]
|
|
125
|
-
*/
|
|
126
|
-
function rsaPublicKeyBytesToKeyObject(rsaBytes) {
|
|
127
|
-
const buf = Buffer.from(rsaBytes);
|
|
128
|
-
let offset = 0;
|
|
129
|
-
const eLen = buf.readUInt32BE(offset);
|
|
130
|
-
offset += 4;
|
|
131
|
-
const e = buf.subarray(offset, offset + eLen);
|
|
132
|
-
offset += eLen;
|
|
133
|
-
const nLen = buf.readUInt32BE(offset);
|
|
134
|
-
offset += 4;
|
|
135
|
-
const n = buf.subarray(offset, offset + nLen);
|
|
136
|
-
// Build a DER-encoded RSA public key (PKCS#1)
|
|
137
|
-
// Use Node.js crypto to create from JWK
|
|
138
|
-
const jwk = {
|
|
139
|
-
kty: 'RSA',
|
|
140
|
-
n: bufferToBase64Url(stripLeadingZero(n)),
|
|
141
|
-
e: bufferToBase64Url(stripLeadingZero(e)),
|
|
142
|
-
};
|
|
143
|
-
return crypto.createPublicKey({ key: jwk, format: 'jwk' });
|
|
144
|
-
}
|
|
145
|
-
function stripLeadingZero(buf) {
|
|
146
|
-
// SSH wire format may have a leading zero byte for sign
|
|
147
|
-
if (buf[0] === 0 && buf.length > 1) {
|
|
148
|
-
return buf.subarray(1);
|
|
149
|
-
}
|
|
150
|
-
return buf;
|
|
151
|
-
}
|
|
152
|
-
function bufferToBase64Url(buf) {
|
|
153
|
-
return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
154
|
-
}
|
|
155
|
-
//# sourceMappingURL=standard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"standard.js","sourceRoot":"","sources":["../../../crypto/tiers/standard.ts"],"names":[],"mappings":"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"}
|