@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.
Files changed (134) hide show
  1. package/dist/cli/bootstrap.d.ts +11 -3
  2. package/dist/cli/bootstrap.d.ts.map +1 -1
  3. package/dist/cli/bootstrap.js +181 -126
  4. package/dist/cli/bootstrap.js.map +1 -1
  5. package/dist/cli/commands/config.d.ts +30 -4
  6. package/dist/cli/commands/config.d.ts.map +1 -1
  7. package/dist/cli/commands/config.js +289 -134
  8. package/dist/cli/commands/config.js.map +1 -1
  9. package/dist/cli/commands/devices.d.ts.map +1 -1
  10. package/dist/cli/commands/devices.js +58 -33
  11. package/dist/cli/commands/devices.js.map +1 -1
  12. package/dist/cli/commands/export.d.ts.map +1 -1
  13. package/dist/cli/commands/export.js +6 -9
  14. package/dist/cli/commands/export.js.map +1 -1
  15. package/dist/cli/commands/import.js +1 -1
  16. package/dist/cli/commands/import.js.map +1 -1
  17. package/dist/cli/commands/projects.d.ts.map +1 -1
  18. package/dist/cli/commands/projects.js +33 -10
  19. package/dist/cli/commands/projects.js.map +1 -1
  20. package/dist/cli/commands/rotate-key.d.ts +3 -3
  21. package/dist/cli/commands/rotate-key.d.ts.map +1 -1
  22. package/dist/cli/commands/rotate-key.js +88 -35
  23. package/dist/cli/commands/rotate-key.js.map +1 -1
  24. package/dist/cli/commands/setup-sync.d.ts.map +1 -1
  25. package/dist/cli/commands/setup-sync.js +22 -4
  26. package/dist/cli/commands/setup-sync.js.map +1 -1
  27. package/dist/cli/index.js +20 -1
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/cli/mcp-server.d.ts +6 -0
  30. package/dist/cli/mcp-server.d.ts.map +1 -1
  31. package/dist/cli/mcp-server.js +93 -42
  32. package/dist/cli/mcp-server.js.map +1 -1
  33. package/dist/crypto/aad.d.ts +2 -5
  34. package/dist/crypto/aad.d.ts.map +1 -1
  35. package/dist/crypto/aad.js +2 -8
  36. package/dist/crypto/aad.js.map +1 -1
  37. package/dist/crypto/aead.d.ts +8 -16
  38. package/dist/crypto/aead.d.ts.map +1 -1
  39. package/dist/crypto/aead.js +10 -36
  40. package/dist/crypto/aead.js.map +1 -1
  41. package/dist/crypto/blob-id.d.ts +2 -3
  42. package/dist/crypto/blob-id.d.ts.map +1 -1
  43. package/dist/crypto/blob-id.js +2 -30
  44. package/dist/crypto/blob-id.js.map +1 -1
  45. package/dist/crypto/canonical-json.d.ts +5 -3
  46. package/dist/crypto/canonical-json.d.ts.map +1 -1
  47. package/dist/crypto/canonical-json.js +5 -85
  48. package/dist/crypto/canonical-json.js.map +1 -1
  49. package/dist/crypto/commitment.d.ts +3 -9
  50. package/dist/crypto/commitment.d.ts.map +1 -1
  51. package/dist/crypto/commitment.js +3 -27
  52. package/dist/crypto/commitment.js.map +1 -1
  53. package/dist/crypto/encryption-service.d.ts +3 -0
  54. package/dist/crypto/encryption-service.d.ts.map +1 -1
  55. package/dist/crypto/encryption-service.js +10 -6
  56. package/dist/crypto/encryption-service.js.map +1 -1
  57. package/dist/crypto/envelope-cbor.d.ts +4 -34
  58. package/dist/crypto/envelope-cbor.d.ts.map +1 -1
  59. package/dist/crypto/envelope-cbor.js +4 -121
  60. package/dist/crypto/envelope-cbor.js.map +1 -1
  61. package/dist/crypto/envelope.d.ts +1 -31
  62. package/dist/crypto/envelope.d.ts.map +1 -1
  63. package/dist/crypto/envelope.js +31 -137
  64. package/dist/crypto/envelope.js.map +1 -1
  65. package/dist/crypto/hkdf.d.ts +7 -11
  66. package/dist/crypto/hkdf.d.ts.map +1 -1
  67. package/dist/crypto/hkdf.js +9 -18
  68. package/dist/crypto/hkdf.js.map +1 -1
  69. package/dist/crypto/index.d.ts +9 -4
  70. package/dist/crypto/index.d.ts.map +1 -1
  71. package/dist/crypto/index.js +9 -4
  72. package/dist/crypto/index.js.map +1 -1
  73. package/dist/crypto/ssh-keys.d.ts +17 -10
  74. package/dist/crypto/ssh-keys.d.ts.map +1 -1
  75. package/dist/crypto/ssh-keys.js +28 -108
  76. package/dist/crypto/ssh-keys.js.map +1 -1
  77. package/dist/crypto/types.d.ts +18 -88
  78. package/dist/crypto/types.d.ts.map +1 -1
  79. package/dist/crypto/types.js +3 -0
  80. package/dist/crypto/types.js.map +1 -1
  81. package/dist/pipeline/content-pipeline.d.ts.map +1 -1
  82. package/dist/pipeline/content-pipeline.js +21 -5
  83. package/dist/pipeline/content-pipeline.js.map +1 -1
  84. package/dist/pipeline/extract.d.ts +8 -0
  85. package/dist/pipeline/extract.d.ts.map +1 -1
  86. package/dist/pipeline/extract.js +15 -4
  87. package/dist/pipeline/extract.js.map +1 -1
  88. package/dist/pipeline/fetch-browser.d.ts +29 -0
  89. package/dist/pipeline/fetch-browser.d.ts.map +1 -0
  90. package/dist/pipeline/fetch-browser.js +98 -0
  91. package/dist/pipeline/fetch-browser.js.map +1 -0
  92. package/dist/pipeline/safety.d.ts +43 -6
  93. package/dist/pipeline/safety.d.ts.map +1 -1
  94. package/dist/pipeline/safety.js +52 -15
  95. package/dist/pipeline/safety.js.map +1 -1
  96. package/dist/pipeline/validate.js +35 -23
  97. package/dist/pipeline/validate.js.map +1 -1
  98. package/package.json +4 -1
  99. package/dist/crypto/argon2.d.ts +0 -11
  100. package/dist/crypto/argon2.d.ts.map +0 -1
  101. package/dist/crypto/argon2.js +0 -33
  102. package/dist/crypto/argon2.js.map +0 -1
  103. package/dist/crypto/invite.d.ts +0 -31
  104. package/dist/crypto/invite.d.ts.map +0 -1
  105. package/dist/crypto/invite.js +0 -139
  106. package/dist/crypto/invite.js.map +0 -1
  107. package/dist/crypto/keyring.d.ts +0 -37
  108. package/dist/crypto/keyring.d.ts.map +0 -1
  109. package/dist/crypto/keyring.js +0 -219
  110. package/dist/crypto/keyring.js.map +0 -1
  111. package/dist/crypto/known-keys.d.ts +0 -34
  112. package/dist/crypto/known-keys.d.ts.map +0 -1
  113. package/dist/crypto/known-keys.js +0 -114
  114. package/dist/crypto/known-keys.js.map +0 -1
  115. package/dist/crypto/project-keys.d.ts +0 -26
  116. package/dist/crypto/project-keys.d.ts.map +0 -1
  117. package/dist/crypto/project-keys.js +0 -69
  118. package/dist/crypto/project-keys.js.map +0 -1
  119. package/dist/crypto/secure-buffer.d.ts +0 -31
  120. package/dist/crypto/secure-buffer.d.ts.map +0 -1
  121. package/dist/crypto/secure-buffer.js +0 -61
  122. package/dist/crypto/secure-buffer.js.map +0 -1
  123. package/dist/crypto/tiers/enhanced.d.ts +0 -25
  124. package/dist/crypto/tiers/enhanced.d.ts.map +0 -1
  125. package/dist/crypto/tiers/enhanced.js +0 -56
  126. package/dist/crypto/tiers/enhanced.js.map +0 -1
  127. package/dist/crypto/tiers/maximum.d.ts +0 -19
  128. package/dist/crypto/tiers/maximum.d.ts.map +0 -1
  129. package/dist/crypto/tiers/maximum.js +0 -25
  130. package/dist/crypto/tiers/maximum.js.map +0 -1
  131. package/dist/crypto/tiers/standard.d.ts +0 -27
  132. package/dist/crypto/tiers/standard.d.ts.map +0 -1
  133. package/dist/crypto/tiers/standard.js +0 -155
  134. 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":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,MAAM,MAAM,eAAe,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAGpF,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,SAAwB,EAAE,YAAwB;IAC9E,IAAI,YAAY,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,eAAe,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IACjE,CAAC;SAAM,IAAI,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACvC,OAAO,WAAW,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;IAC7D,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,6BAA6B,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAsB,EACtB,gBAA4B,EAC5B,gBAA4B;IAE5B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAE5D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,CAAC,oBAAoB,CACzB,SAAS,EACT,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EACvB,KAAK,EACL,KAAK,CACN,CAAC;QACF,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,UAAsB,EACtB,aAA+B;IAE/B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,mCAAmC;IACnC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,IAAI,CAAC,CAAC;IAEZ,4BAA4B;IAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;IAC9D,MAAM,IAAI,YAAY,CAAC;IAEvB,6EAA6E;IAC7E,MAAM,WAAW,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,EAAE,EAAE,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACrE,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAE1D,qCAAqC;IACrC,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CACvC;QACE,GAAG,EAAE,aAAa;QAClB,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,sBAAsB;QAChD,QAAQ,EAAE,QAAQ;KACnB,EACD,SAAS,CACV,CAAC;IAEF,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,cAAc,GAAG,WAAW,CAChC,IAAI,UAAU,CAAC,WAAW,CAAC,EAC3B,IAAI,UAAU,CAAC,KAAK,CAAC,EACrB,IAAI,UAAU,CAAC,UAAU,CAAC,EAC1B,IAAI,UAAU,CAAC,GAAG,CAAC,EACnB,QAAQ,CACT,CAAC;IAEF,wBAAwB;IACxB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpB,OAAO,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,2BAA2B;AAE3B,SAAS,eAAe,CAAC,SAAwB,EAAE,gBAA4B;IAC7E,MAAM,QAAQ,GAAG,wBAAwB,CAAC,gBAAgB,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5E,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAExE,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,WAAW,CAAC,SAAwB,EAAE,iBAA6B;IAC1E,uEAAuE;IACvE,MAAM,SAAS,GAAG,4BAA4B,CAAC,iBAAiB,CAAC,CAAC;IAElE,yBAAyB;IACzB,MAAM,SAAS,GAAI,SAAuD,CAAC,iBAAiB,CAAC;IAC7F,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,GAAG,YAAY,EAAE,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,GAAG,CAAC,kBAAkB,YAAY,GAAG,CAAC,CAAC;IACxF,CAAC;IAED,uCAAuC;IACvC,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAE3C,oCAAoC;IACpC,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CACpC;QACE,GAAG,EAAE,SAAS;QACd,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,sBAAsB;QAChD,QAAQ,EAAE,QAAQ;KACnB,EACD,WAAW,CACZ,CAAC;IAEF,kEAAkE;IAClE,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,WAAW,CAC5C,IAAI,UAAU,CAAC,WAAW,CAAC,EAC3B,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,EAChC,QAAQ,CACT,CAAC;IAEF,wBAAwB;IACxB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpB,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,IAAI,CAAC,CAAC;IACZ,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,IAAI,SAAS,CAAC,MAAM,CAAC;IAC3B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IACvB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC;IAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,SAAS,4BAA4B,CAAC,QAAoB;IACxD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,IAAI,CAAC,CAAC;IACZ,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9C,MAAM,IAAI,IAAI,CAAC;IAEf,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,IAAI,CAAC,CAAC;IACZ,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;IAE9C,8CAA8C;IAC9C,wCAAwC;IACxC,MAAM,GAAG,GAAG;QACV,GAAG,EAAE,KAAK;QACV,CAAC,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC,EAAE,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;KAC1C,CAAC;IAEF,OAAO,MAAM,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,wDAAwD;IACxD,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3F,CAAC"}