@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,124 +1,7 @@
1
1
  /**
2
- * CBOR serialization for ChaosKB envelopes (v2 wire format).
3
- *
4
- * v2 envelopes store ciphertext and commitment as raw binary (Uint8Array)
5
- * instead of base64, saving ~33% size overhead on the ciphertext field.
6
- *
7
- * Backward compatibility: can read both v1 (JSON) and v2 (CBOR) envelopes.
2
+ * chaoskb's CBOR envelope helpers, aliased to the `@de-otio/crypto-envelope`
3
+ * implementations. Preserves the historical chaoskb names
4
+ * (`serializeEnvelopeCBOR`, `deserializeEnvelope`).
8
5
  */
9
- import { encode, decode } from 'cborg';
10
- /** CBOR tag used to identify ChaosKB envelopes (arbitrary, in private range). */
11
- const CHAOSKB_CBOR_MAGIC = new Uint8Array([0x43, 0x4b, 0x42]); // "CKB"
12
- /**
13
- * Serialize an envelope to CBOR binary format (v2).
14
- *
15
- * @param envelope - A v2 envelope with raw binary ct and commit.
16
- * @returns CBOR-encoded bytes.
17
- */
18
- export function serializeEnvelopeCBOR(envelope) {
19
- const cborPayload = {
20
- v: envelope.v,
21
- id: envelope.id,
22
- ts: envelope.ts,
23
- enc: {
24
- alg: envelope.enc.alg,
25
- kid: envelope.enc.kid,
26
- ct: envelope.enc.ct,
27
- commit: envelope.enc.commit,
28
- },
29
- };
30
- const cborBytes = encode(cborPayload);
31
- // Prepend magic header so we can distinguish CBOR from JSON
32
- const result = new Uint8Array(CHAOSKB_CBOR_MAGIC.length + cborBytes.length);
33
- result.set(CHAOSKB_CBOR_MAGIC, 0);
34
- result.set(cborBytes, CHAOSKB_CBOR_MAGIC.length);
35
- return result;
36
- }
37
- /**
38
- * Deserialize bytes into an envelope, auto-detecting the format.
39
- *
40
- * - If bytes start with "CKB" magic header, decode as CBOR (v2)
41
- * - If bytes start with '{', decode as JSON (v1)
42
- *
43
- * @param bytes - Raw envelope bytes.
44
- * @returns Parsed envelope (v1 or v2).
45
- */
46
- export function deserializeEnvelope(bytes) {
47
- // Check for CBOR magic header
48
- if (bytes.length >= CHAOSKB_CBOR_MAGIC.length &&
49
- bytes[0] === CHAOSKB_CBOR_MAGIC[0] &&
50
- bytes[1] === CHAOSKB_CBOR_MAGIC[1] &&
51
- bytes[2] === CHAOSKB_CBOR_MAGIC[2]) {
52
- return deserializeCBOR(bytes.subarray(CHAOSKB_CBOR_MAGIC.length));
53
- }
54
- // Try JSON (v1)
55
- return deserializeJSON(bytes);
56
- }
57
- /**
58
- * Decode CBOR bytes into a v2 envelope.
59
- */
60
- function deserializeCBOR(cborBytes) {
61
- const parsed = decode(cborBytes);
62
- if (parsed.v !== 2) {
63
- throw new Error(`CBOR envelope has unexpected version: ${parsed.v}`);
64
- }
65
- return {
66
- v: 2,
67
- id: parsed.id,
68
- ts: parsed.ts,
69
- enc: {
70
- alg: parsed.enc.alg,
71
- kid: parsed.enc.kid,
72
- ct: new Uint8Array(parsed.enc.ct),
73
- commit: new Uint8Array(parsed.enc.commit),
74
- },
75
- };
76
- }
77
- /**
78
- * Decode JSON bytes into a v1 envelope.
79
- */
80
- function deserializeJSON(bytes) {
81
- const json = new TextDecoder().decode(bytes);
82
- const parsed = JSON.parse(json);
83
- if (parsed.v !== 1) {
84
- throw new Error(`JSON envelope has unexpected version: ${parsed.v}`);
85
- }
86
- return parsed;
87
- }
88
- /**
89
- * Convert a v1 (JSON) envelope to a v2 (CBOR) envelope.
90
- * Decodes base64 fields to raw binary.
91
- */
92
- export function upgradeToV2(v1) {
93
- return {
94
- v: 2,
95
- id: v1.id,
96
- ts: v1.ts,
97
- enc: {
98
- alg: v1.enc.alg,
99
- kid: v1.enc.kid,
100
- ct: new Uint8Array(Buffer.from(v1.enc.ct, 'base64')),
101
- commit: new Uint8Array(Buffer.from(v1.enc.commit, 'base64')),
102
- },
103
- };
104
- }
105
- /**
106
- * Convert a v2 (CBOR) envelope back to v1 (JSON) format.
107
- * Encodes binary fields as base64.
108
- */
109
- export function downgradeToV1(v2) {
110
- const ctBase64 = Buffer.from(v2.enc.ct).toString('base64');
111
- return {
112
- v: 1,
113
- id: v2.id,
114
- ts: v2.ts,
115
- enc: {
116
- alg: v2.enc.alg,
117
- kid: v2.enc.kid,
118
- ct: ctBase64,
119
- 'ct.len': v2.enc.ct.length,
120
- commit: Buffer.from(v2.enc.commit).toString('base64'),
121
- },
122
- };
123
- }
6
+ export { serializeV2 as serializeEnvelopeCBOR, deserialize as deserializeEnvelope, upgradeToV2, downgradeToV1, } from '@de-otio/crypto-envelope';
124
7
  //# sourceMappingURL=envelope-cbor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"envelope-cbor.js","sourceRoot":"","sources":["../../crypto/envelope-cbor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"envelope-cbor.js","sourceRoot":"","sources":["../../crypto/envelope-cbor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,WAAW,IAAI,qBAAqB,EACpC,WAAW,IAAI,mBAAmB,EAClC,WAAW,EACX,aAAa,GACd,MAAM,0BAA0B,CAAC"}
@@ -1,34 +1,4 @@
1
- import type { DerivedKeySet, DecryptResult, EncryptResult, Envelope, KeyId, Payload } from './types.js';
2
- /**
3
- * Encrypt a payload into an envelope (v1).
4
- *
5
- * Steps per the envelope spec:
6
- * 1. Serialize payload to canonical JSON, convert to UTF-8 bytes
7
- * 2. Generate blob ID
8
- * 3. Select key by kid (default CEK)
9
- * 4. Construct AAD
10
- * 5. Encrypt with AEAD
11
- * 6. Concatenate: rawCt = nonce || ciphertext || tag
12
- * 7. Compute commitment: HMAC-SHA256(commitKey, blobId || rawCt)
13
- * 8. Verify-after-encrypt: decrypt rawCt, compare with original plaintext
14
- * 9. Base64-encode ct and commit
15
- * 10. Assemble Envelope object
16
- * 11. Return EncryptResult with envelope and serialized JSON bytes
17
- */
1
+ import type { DecryptResult, DerivedKeySet, EncryptResult, Envelope, KeyId, Payload } from './types.js';
18
2
  export declare function encryptPayload(payload: Payload, keys: DerivedKeySet, kid?: KeyId): EncryptResult;
19
- /**
20
- * Decrypt an envelope into a payload.
21
- *
22
- * Steps per the envelope spec:
23
- * 1. Check v == 1
24
- * 2. Base64-decode ct
25
- * 3. Verify ct.len matches decoded length
26
- * 4. Verify key commitment
27
- * 5. Construct AAD
28
- * 6. Split rawCt into nonce, ciphertext, tag
29
- * 7. Decrypt
30
- * 8. Parse plaintext as JSON, validate type field
31
- * 9. Return DecryptResult
32
- */
33
3
  export declare function decryptEnvelope(envelope: Envelope, keys: DerivedKeySet): DecryptResult;
34
4
  //# sourceMappingURL=envelope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,KAAK,EACL,OAAO,EACR,MAAM,YAAY,CAAC;AAwBpB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,GAAG,GAAE,KAAa,GACjB,aAAa,CA0Df;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,aAAa,CA0DtF"}
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,KAAK,EACL,OAAO,EACR,MAAM,YAAY,CAAC;AA0BpB,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,GAAG,GAAE,KAAa,GACjB,aAAa,CAUf;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,aAAa,CAmBtF"}
@@ -1,16 +1,11 @@
1
- import * as crypto from 'node:crypto';
2
- import { aeadDecrypt, aeadEncrypt } from './aead.js';
3
- import { constructAAD } from './aad.js';
4
- import { generateBlobId } from './blob-id.js';
5
- import { canonicalJson } from './canonical-json.js';
6
- import { computeCommitment, verifyCommitment } from './commitment.js';
7
- // Algorithm parameters: nonce size and tag size
8
- const ALG_PARAMS = {
9
- 'XChaCha20-Poly1305': { nonceSize: 24, tagSize: 16 },
10
- 'AES-256-GCM': { nonceSize: 12, tagSize: 16 },
11
- };
1
+ import { decryptV1, encryptV1 } from '@de-otio/crypto-envelope';
12
2
  /**
13
- * Look up the encryption key for a given key identifier.
3
+ * chaoskb's envelope API, adapted to delegate to `@de-otio/crypto-envelope`.
4
+ *
5
+ * The package takes explicit `cek` and `commitKey` bytes; chaoskb's callers
6
+ * still pass a `DerivedKeySet` and a `KeyId`, so this adapter unpacks the
7
+ * right key by `kid` and validates the chaoskb-specific payload type on
8
+ * decrypt.
14
9
  */
15
10
  function getKey(keys, kid) {
16
11
  switch (kid) {
@@ -20,137 +15,36 @@ function getKey(keys, kid) {
20
15
  return new Uint8Array(keys.metadataKey.buffer);
21
16
  case 'EEK':
22
17
  return new Uint8Array(keys.embeddingKey.buffer);
23
- default:
24
- throw new Error(`Unknown key identifier: ${kid}`);
18
+ default: {
19
+ const _exhaustive = kid;
20
+ throw new Error(`Unknown key identifier: ${_exhaustive}`);
21
+ }
25
22
  }
26
23
  }
27
- /**
28
- * Encrypt a payload into an envelope (v1).
29
- *
30
- * Steps per the envelope spec:
31
- * 1. Serialize payload to canonical JSON, convert to UTF-8 bytes
32
- * 2. Generate blob ID
33
- * 3. Select key by kid (default CEK)
34
- * 4. Construct AAD
35
- * 5. Encrypt with AEAD
36
- * 6. Concatenate: rawCt = nonce || ciphertext || tag
37
- * 7. Compute commitment: HMAC-SHA256(commitKey, blobId || rawCt)
38
- * 8. Verify-after-encrypt: decrypt rawCt, compare with original plaintext
39
- * 9. Base64-encode ct and commit
40
- * 10. Assemble Envelope object
41
- * 11. Return EncryptResult with envelope and serialized JSON bytes
42
- */
43
24
  export function encryptPayload(payload, keys, kid = 'CEK') {
44
- const alg = 'XChaCha20-Poly1305';
45
- // 1. Serialize to canonical JSON
46
- const json = canonicalJson(payload);
47
- const plaintextBytes = new TextEncoder().encode(json);
48
- // 2. Generate blob ID
49
- const blobId = generateBlobId();
50
- // 3. Select encryption key
51
- const encKey = getKey(keys, kid);
52
- // 4. Construct AAD
53
- const aad = constructAAD(alg, blobId, kid, 1);
54
- // 5. Encrypt
55
- const { nonce, ciphertext, tag } = aeadEncrypt(encKey, plaintextBytes, aad);
56
- // 6. Concatenate: rawCt = nonce || ciphertext || tag
57
- const rawCt = new Uint8Array(nonce.length + ciphertext.length + tag.length);
58
- rawCt.set(nonce, 0);
59
- rawCt.set(ciphertext, nonce.length);
60
- rawCt.set(tag, nonce.length + ciphertext.length);
61
- // 7. Compute key commitment
62
- const commitKey = new Uint8Array(keys.commitKey.buffer);
63
- const commitment = computeCommitment(commitKey, blobId, rawCt);
64
- // 8. Verify-after-encrypt: decrypt and compare
65
- const recovered = aeadDecrypt(encKey, nonce, ciphertext, tag, aad);
66
- if (!constantTimeEqual(recovered, plaintextBytes)) {
67
- throw new Error('Verify-after-encrypt failed: decrypted plaintext does not match original');
68
- }
69
- // 9. Base64-encode
70
- const ctBase64 = Buffer.from(rawCt).toString('base64');
71
- const commitBase64 = Buffer.from(commitment).toString('base64');
72
- // 10. Assemble envelope
73
- const envelope = {
74
- v: 1,
75
- id: blobId,
76
- ts: new Date().toISOString(),
77
- enc: {
78
- alg,
79
- kid,
80
- ct: ctBase64,
81
- 'ct.len': rawCt.length,
82
- commit: commitBase64,
83
- },
84
- };
85
- // 11. Serialize envelope to bytes
86
- const envelopeJson = JSON.stringify(envelope);
87
- const bytes = new TextEncoder().encode(envelopeJson);
25
+ const envelope = encryptV1({
26
+ payload: payload,
27
+ cek: getKey(keys, kid),
28
+ commitKey: new Uint8Array(keys.commitKey.buffer),
29
+ kid,
30
+ });
31
+ const bytes = new TextEncoder().encode(JSON.stringify(envelope));
88
32
  return { envelope, bytes };
89
33
  }
90
- /**
91
- * Decrypt an envelope into a payload.
92
- *
93
- * Steps per the envelope spec:
94
- * 1. Check v == 1
95
- * 2. Base64-decode ct
96
- * 3. Verify ct.len matches decoded length
97
- * 4. Verify key commitment
98
- * 5. Construct AAD
99
- * 6. Split rawCt into nonce, ciphertext, tag
100
- * 7. Decrypt
101
- * 8. Parse plaintext as JSON, validate type field
102
- * 9. Return DecryptResult
103
- */
104
- export function decryptEnvelope(envelope, keys) {
105
- // 1. Check version
106
- if (envelope.v !== 1) {
107
- throw new Error(`Unsupported envelope version: ${envelope.v}. Please update the app.`);
108
- }
109
- const alg = envelope.enc.alg;
110
- const params = ALG_PARAMS[alg];
111
- if (!params) {
112
- throw new Error(`Unsupported algorithm: ${alg}`);
113
- }
114
- // 2. Base64-decode ct
115
- const rawCt = new Uint8Array(Buffer.from(envelope.enc.ct, 'base64'));
116
- // Verify minimum length
117
- const minLength = params.nonceSize + params.tagSize + 1;
118
- if (rawCt.length < minLength) {
119
- throw new Error(`Truncated ciphertext: expected at least ${minLength} bytes, got ${rawCt.length}`);
120
- }
121
- // 3. Verify ct.len
122
- if (envelope.enc['ct.len'] !== undefined && rawCt.length !== envelope.enc['ct.len']) {
123
- throw new Error(`Ciphertext length mismatch: ct.len=${envelope.enc['ct.len']}, actual=${rawCt.length}`);
34
+ function toKeyId(kid) {
35
+ if (kid === 'CEK' || kid === 'MEK' || kid === 'EEK') {
36
+ return kid;
124
37
  }
125
- // 4. Verify key commitment
126
- const commitKey = new Uint8Array(keys.commitKey.buffer);
127
- const expectedCommit = new Uint8Array(Buffer.from(envelope.enc.commit, 'base64'));
128
- if (!verifyCommitment(commitKey, envelope.id, rawCt, expectedCommit)) {
129
- throw new Error('Key commitment verification failed');
130
- }
131
- // 5. Construct AAD
132
- const aad = constructAAD(alg, envelope.id, envelope.enc.kid, envelope.v);
133
- // 6. Split rawCt into nonce, ciphertext, tag
134
- const nonce = rawCt.slice(0, params.nonceSize);
135
- const ciphertext = rawCt.slice(params.nonceSize, rawCt.length - params.tagSize);
136
- const tag = rawCt.slice(rawCt.length - params.tagSize);
137
- // 7. Decrypt
138
- const encKey = getKey(keys, envelope.enc.kid);
139
- const plaintext = aeadDecrypt(encKey, nonce, ciphertext, tag, aad);
140
- // 8. Parse plaintext as JSON
141
- const json = new TextDecoder().decode(plaintext);
142
- const payload = JSON.parse(json);
143
- // Validate type field exists
144
- if (!payload.type || !['source', 'chunk', 'canary'].includes(payload.type)) {
145
- throw new Error(`Invalid payload type: ${payload.type}`);
146
- }
147
- // 9. Return result
148
- return { payload, envelope };
38
+ throw new Error(`Unknown key identifier: ${kid}`);
149
39
  }
150
- function constantTimeEqual(a, b) {
151
- if (a.length !== b.length) {
152
- return false;
153
- }
154
- return crypto.timingSafeEqual(a, b);
40
+ export function decryptEnvelope(envelope, keys) {
41
+ const plaintext = decryptV1(envelope, getKey(keys, toKeyId(envelope.enc.kid)), new Uint8Array(keys.commitKey.buffer));
42
+ // chaoskb-specific payload-type validation — the generic envelope
43
+ // package doesn't know which payload shapes chaoskb considers valid.
44
+ if (!plaintext.type ||
45
+ !['source', 'chunk', 'canary'].includes(plaintext.type)) {
46
+ throw new Error(`Invalid payload type: ${plaintext.type}`);
47
+ }
48
+ return { payload: plaintext, envelope };
155
49
  }
156
50
  //# sourceMappingURL=envelope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAUhE;;;;;;;GAOG;AAEH,SAAS,MAAM,CAAC,IAAmB,EAAE,GAAU;IAC7C,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,KAAK;YACR,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAChD,KAAK,KAAK;YACR,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACjD,KAAK,KAAK;YACR,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,GAAG,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,2BAA2B,WAAW,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,OAAgB,EAChB,IAAmB,EACnB,MAAa,KAAK;IAElB,MAAM,QAAQ,GAAG,SAAS,CAAC;QACzB,OAAO,EAAE,OAA6C;QACtD,GAAG,EAAE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC;QACtB,SAAS,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;QAChD,GAAG;KACJ,CAAa,CAAC;IAEf,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QACpD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAkB,EAAE,IAAmB;IACrE,MAAM,SAAS,GAAG,SAAS,CACzB,QAAQ,EACR,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EACvC,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAChB,CAAC;IAExB,kEAAkE;IAClE,qEAAqE;IACrE,IACE,CAAC,SAAS,CAAC,IAAI;QACf,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,EACvD,CAAC;QACD,MAAM,IAAI,KAAK,CACb,yBAA0B,SAAgD,CAAC,IAAI,EAAE,CAClF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC1C,CAAC"}
@@ -1,16 +1,12 @@
1
+ import { deriveKey } from '@de-otio/crypto-envelope/primitives';
1
2
  import type { DerivedKeySet } from './types.js';
3
+ export { deriveKey };
2
4
  /**
3
- * Derive a key using HKDF-SHA256 (Extract+Expand per RFC 5869).
4
- * @param ikm - Input keying material
5
- * @param info - Context/application-specific info string
6
- * @param salt - Optional salt (defaults to empty Uint8Array)
7
- * @param length - Output key length in bytes (default 32)
8
- */
9
- export declare function deriveKey(ikm: Uint8Array, info: string, salt?: Uint8Array, length?: number): Uint8Array;
10
- /**
11
- * Derive the complete set of subkeys from a master key.
12
- * Returns SecureBuffer-wrapped keys for:
13
- * CEK (content), MEK (metadata), EEK (embedding), CKY (commit)
5
+ * Derive the four chaoskb subkeys from a master key via HKDF-SHA256.
6
+ *
7
+ * Info strings are chaoskb-specific and MUST NOT change — every encrypted
8
+ * blob on disk was bound to these labels at encrypt time, and changing them
9
+ * would mean no existing envelope could decrypt.
14
10
  */
15
11
  export declare function deriveKeySet(masterKey: Uint8Array, salt?: Uint8Array): DerivedKeySet;
16
12
  //# sourceMappingURL=hkdf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["../../crypto/hkdf.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAGZ;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,aAAa,CAYpF"}
1
+ {"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["../../crypto/hkdf.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAEhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,aAAa,CAYpF"}
@@ -1,22 +1,13 @@
1
- import { hkdf } from '@noble/hashes/hkdf.js';
2
- import { sha256 } from '@noble/hashes/sha2.js';
3
- import { SecureBuffer } from './secure-buffer.js';
4
- const DEFAULT_KEY_LENGTH = 32;
1
+ import { SecureBuffer } from '@de-otio/crypto-envelope';
2
+ import { deriveKey } from '@de-otio/crypto-envelope/primitives';
3
+ // Re-export `deriveKey` so callers that import it from this module keep working.
4
+ export { deriveKey };
5
5
  /**
6
- * Derive a key using HKDF-SHA256 (Extract+Expand per RFC 5869).
7
- * @param ikm - Input keying material
8
- * @param info - Context/application-specific info string
9
- * @param salt - Optional salt (defaults to empty Uint8Array)
10
- * @param length - Output key length in bytes (default 32)
11
- */
12
- export function deriveKey(ikm, info, salt, length) {
13
- const infoBytes = new TextEncoder().encode(info);
14
- return hkdf(sha256, ikm, salt ?? new Uint8Array(0), infoBytes, length ?? DEFAULT_KEY_LENGTH);
15
- }
16
- /**
17
- * Derive the complete set of subkeys from a master key.
18
- * Returns SecureBuffer-wrapped keys for:
19
- * CEK (content), MEK (metadata), EEK (embedding), CKY (commit)
6
+ * Derive the four chaoskb subkeys from a master key via HKDF-SHA256.
7
+ *
8
+ * Info strings are chaoskb-specific and MUST NOT change — every encrypted
9
+ * blob on disk was bound to these labels at encrypt time, and changing them
10
+ * would mean no existing envelope could decrypt.
20
11
  */
21
12
  export function deriveKeySet(masterKey, salt) {
22
13
  const cekBytes = deriveKey(masterKey, 'chaoskb-content', salt);
@@ -1 +1 @@
1
- {"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../../crypto/hkdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,GAAe,EACf,IAAY,EACZ,IAAiB,EACjB,MAAe;IAEf,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,IAAI,kBAAkB,CAAC,CAAC;AAC/F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAqB,EAAE,IAAiB;IACnE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAE9D,OAAO;QACL,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KACpD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"hkdf.js","sourceRoot":"","sources":["../../crypto/hkdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAIhE,iFAAiF;AACjF,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,SAAqB,EAAE,IAAiB;IACnE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAE9D,OAAO;QACL,UAAU,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,SAAS,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KACpD,CAAC;AACJ,CAAC"}
@@ -1,15 +1,20 @@
1
+ /**
2
+ * chaoskb crypto module — knowledge-base blob primitives.
3
+ *
4
+ * Key-lifecycle (master-key wrapping, tiers, project keys, invites,
5
+ * TOFU pinning) lives in `@de-otio/keyring`. Pre-existing re-exports
6
+ * of those modules have been removed.
7
+ */
1
8
  export * from './types.js';
2
- export { SecureBuffer } from './secure-buffer.js';
9
+ export { SecureBuffer } from '@de-otio/crypto-envelope';
3
10
  export { canonicalJson } from './canonical-json.js';
4
11
  export { generateBlobId } from './blob-id.js';
5
12
  export { aeadEncrypt, aeadDecrypt } from './aead.js';
6
13
  export { deriveKey, deriveKeySet } from './hkdf.js';
7
- export { deriveFromPassphrase as argon2Derive } from './argon2.js';
14
+ export { deriveFromPassphrase as argon2Derive } from '@de-otio/crypto-envelope/primitives';
8
15
  export { constructAAD } from './aad.js';
9
16
  export { computeCommitment, verifyCommitment } from './commitment.js';
10
17
  export { encryptPayload, decryptEnvelope } from './envelope.js';
11
18
  export { parseSSHPublicKey, ed25519ToX25519PublicKey, ed25519ToX25519SecretKey } from './ssh-keys.js';
12
19
  export { EncryptionService } from './encryption-service.js';
13
- export { KeyringService } from './keyring.js';
14
- export { createProjectKey, unwrapProjectKey } from './project-keys.js';
15
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../crypto/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,oBAAoB,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../crypto/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,oBAAoB,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,15 +1,20 @@
1
+ /**
2
+ * chaoskb crypto module — knowledge-base blob primitives.
3
+ *
4
+ * Key-lifecycle (master-key wrapping, tiers, project keys, invites,
5
+ * TOFU pinning) lives in `@de-otio/keyring`. Pre-existing re-exports
6
+ * of those modules have been removed.
7
+ */
1
8
  export * from './types.js';
2
- export { SecureBuffer } from './secure-buffer.js';
9
+ export { SecureBuffer } from '@de-otio/crypto-envelope';
3
10
  export { canonicalJson } from './canonical-json.js';
4
11
  export { generateBlobId } from './blob-id.js';
5
12
  export { aeadEncrypt, aeadDecrypt } from './aead.js';
6
13
  export { deriveKey, deriveKeySet } from './hkdf.js';
7
- export { deriveFromPassphrase as argon2Derive } from './argon2.js';
14
+ export { deriveFromPassphrase as argon2Derive } from '@de-otio/crypto-envelope/primitives';
8
15
  export { constructAAD } from './aad.js';
9
16
  export { computeCommitment, verifyCommitment } from './commitment.js';
10
17
  export { encryptPayload, decryptEnvelope } from './envelope.js';
11
18
  export { parseSSHPublicKey, ed25519ToX25519PublicKey, ed25519ToX25519SecretKey } from './ssh-keys.js';
12
19
  export { EncryptionService } from './encryption-service.js';
13
- export { KeyringService } from './keyring.js';
14
- export { createProjectKey, unwrapProjectKey } from './project-keys.js';
15
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../crypto/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,oBAAoB,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../crypto/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,oBAAoB,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,19 +1,26 @@
1
- import type { SSHKeyInfo } from './types.js';
2
1
  /**
3
- * Parse an OpenSSH public key from authorized_keys / .pub file format.
4
- * Supports ssh-ed25519 and ssh-rsa key types.
2
+ * SSH key helpers thin re-exports over `@de-otio/keyring`'s
3
+ * canonical implementations. Kept so existing chaoskb imports
4
+ * (`parseSSHPublicKey`, `ed25519ToX25519*`) continue to work.
5
5
  *
6
- * Format: <key-type> <base64-blob> [comment]
6
+ * New code should import directly from `@de-otio/keyring`.
7
7
  */
8
+ import { sshFingerprint, type SshKeyType } from '@de-otio/keyring';
9
+ import type { SSHKeyInfo } from './types.js';
10
+ /** Back-compat alias for `parseSshPublicKey`. */
8
11
  export declare function parseSSHPublicKey(keyString: string): SSHKeyInfo;
9
- /**
10
- * Convert an Ed25519 public key to X25519 (Curve25519) public key.
11
- * Uses sodium crypto_sign_ed25519_pk_to_curve25519.
12
- */
12
+ export { sshFingerprint };
13
+ export type { SshKeyType };
14
+ /** Convert an Ed25519 public key to X25519 (Curve25519). */
13
15
  export declare function ed25519ToX25519PublicKey(ed25519PublicKey: Uint8Array): Uint8Array;
14
16
  /**
15
- * Convert an Ed25519 secret key to X25519 (Curve25519) secret key.
16
- * Uses sodium crypto_sign_ed25519_sk_to_curve25519.
17
+ * Convert an Ed25519 secret key to X25519 secret key.
18
+ *
19
+ * Note: keyring's canonical implementation returns an `ISecureBuffer`
20
+ * (design-review B5 fix). For back-compat with the old chaoskb signature
21
+ * we copy the bytes into a plain `Uint8Array` and dispose the secure
22
+ * handle. Callers that want the secure-buffer form should import from
23
+ * `@de-otio/keyring` directly.
17
24
  */
18
25
  export declare function ed25519ToX25519SecretKey(ed25519SecretKey: Uint8Array): Uint8Array;
19
26
  //# sourceMappingURL=ssh-keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-keys.d.ts","sourceRoot":"","sources":["../../crypto/ssh-keys.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAEzD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAqC/D;AAkED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,UAAU,GAAG,UAAU,CAKjF;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,UAAU,GAAG,UAAU,CAMjF"}
1
+ {"version":3,"file":"ssh-keys.d.ts","sourceRoot":"","sources":["../../crypto/ssh-keys.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAEL,cAAc,EAGd,KAAK,UAAU,EAEhB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAEzD,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAQ/D;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,4DAA4D;AAC5D,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,UAAU,GAAG,UAAU,CAEjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,UAAU,GAAG,UAAU,CAOjF"}