@zapo-js/fake-server 0.3.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 +176 -0
- package/dist/api/AppStateSyncManager.d.ts +27 -0
- package/dist/api/AppStateSyncManager.d.ts.map +1 -0
- package/dist/api/AppStateSyncManager.js +151 -0
- package/dist/api/AppStateSyncManager.js.map +1 -0
- package/dist/api/FakePairingDriver.d.ts +27 -0
- package/dist/api/FakePairingDriver.d.ts.map +1 -0
- package/dist/api/FakePairingDriver.js +36 -0
- package/dist/api/FakePairingDriver.js.map +1 -0
- package/dist/api/FakePeer.d.ts +143 -0
- package/dist/api/FakePeer.d.ts.map +1 -0
- package/dist/api/FakePeer.js +408 -0
- package/dist/api/FakePeer.js.map +1 -0
- package/dist/api/FakeWaServer.d.ts +167 -0
- package/dist/api/FakeWaServer.d.ts.map +1 -0
- package/dist/api/FakeWaServer.js +652 -0
- package/dist/api/FakeWaServer.js.map +1 -0
- package/dist/api/PreKeyDispenser.d.ts +23 -0
- package/dist/api/PreKeyDispenser.d.ts.map +1 -0
- package/dist/api/PreKeyDispenser.js +98 -0
- package/dist/api/PreKeyDispenser.js.map +1 -0
- package/dist/api/Scenario.d.ts +24 -0
- package/dist/api/Scenario.d.ts.map +1 -0
- package/dist/api/Scenario.js +38 -0
- package/dist/api/Scenario.js.map +1 -0
- package/dist/api/ServerRegistries.d.ts +110 -0
- package/dist/api/ServerRegistries.d.ts.map +1 -0
- package/dist/api/ServerRegistries.js +268 -0
- package/dist/api/ServerRegistries.js.map +1 -0
- package/dist/api/iq-handlers.d.ts +47 -0
- package/dist/api/iq-handlers.d.ts.map +1 -0
- package/dist/api/iq-handlers.js +498 -0
- package/dist/api/iq-handlers.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +249 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/WaFakeConnection.d.ts +23 -0
- package/dist/infra/WaFakeConnection.d.ts.map +1 -0
- package/dist/infra/WaFakeConnection.js +54 -0
- package/dist/infra/WaFakeConnection.js.map +1 -0
- package/dist/infra/WaFakeConnectionPipeline.d.ts +51 -0
- package/dist/infra/WaFakeConnectionPipeline.d.ts.map +1 -0
- package/dist/infra/WaFakeConnectionPipeline.js +224 -0
- package/dist/infra/WaFakeConnectionPipeline.js.map +1 -0
- package/dist/infra/WaFakeFrameSocket.d.ts +29 -0
- package/dist/infra/WaFakeFrameSocket.d.ts.map +1 -0
- package/dist/infra/WaFakeFrameSocket.js +122 -0
- package/dist/infra/WaFakeFrameSocket.js.map +1 -0
- package/dist/infra/WaFakeMediaHttpsServer.d.ts +16 -0
- package/dist/infra/WaFakeMediaHttpsServer.d.ts.map +1 -0
- package/dist/infra/WaFakeMediaHttpsServer.js +131 -0
- package/dist/infra/WaFakeMediaHttpsServer.js.map +1 -0
- package/dist/infra/WaFakeNoiseHandshake.d.ts +23 -0
- package/dist/infra/WaFakeNoiseHandshake.d.ts.map +1 -0
- package/dist/infra/WaFakeNoiseHandshake.js +76 -0
- package/dist/infra/WaFakeNoiseHandshake.js.map +1 -0
- package/dist/infra/WaFakeTransport.d.ts +15 -0
- package/dist/infra/WaFakeTransport.d.ts.map +1 -0
- package/dist/infra/WaFakeTransport.js +34 -0
- package/dist/infra/WaFakeTransport.js.map +1 -0
- package/dist/infra/WaFakeWsServer.d.ts +29 -0
- package/dist/infra/WaFakeWsServer.d.ts.map +1 -0
- package/dist/infra/WaFakeWsServer.js +101 -0
- package/dist/infra/WaFakeWsServer.js.map +1 -0
- package/dist/protocol/auth/cert-chain.d.ts +18 -0
- package/dist/protocol/auth/cert-chain.d.ts.map +1 -0
- package/dist/protocol/auth/cert-chain.js +44 -0
- package/dist/protocol/auth/cert-chain.js.map +1 -0
- package/dist/protocol/auth/client-payload-validate.d.ts +21 -0
- package/dist/protocol/auth/client-payload-validate.d.ts.map +1 -0
- package/dist/protocol/auth/client-payload-validate.js +61 -0
- package/dist/protocol/auth/client-payload-validate.js.map +1 -0
- package/dist/protocol/auth/fake-primary-device.d.ts +19 -0
- package/dist/protocol/auth/fake-primary-device.d.ts.map +1 -0
- package/dist/protocol/auth/fake-primary-device.js +53 -0
- package/dist/protocol/auth/fake-primary-device.js.map +1 -0
- package/dist/protocol/auth/pair-device.d.ts +26 -0
- package/dist/protocol/auth/pair-device.d.ts.map +1 -0
- package/dist/protocol/auth/pair-device.js +104 -0
- package/dist/protocol/auth/pair-device.js.map +1 -0
- package/dist/protocol/auth/success-node.d.ts +15 -0
- package/dist/protocol/auth/success-node.d.ts.map +1 -0
- package/dist/protocol/auth/success-node.js +30 -0
- package/dist/protocol/auth/success-node.js.map +1 -0
- package/dist/protocol/iq/abprops.d.ts +14 -0
- package/dist/protocol/iq/abprops.d.ts.map +1 -0
- package/dist/protocol/iq/abprops.js +34 -0
- package/dist/protocol/iq/abprops.js.map +1 -0
- package/dist/protocol/iq/appstate-sync.d.ts +38 -0
- package/dist/protocol/iq/appstate-sync.d.ts.map +1 -0
- package/dist/protocol/iq/appstate-sync.js +154 -0
- package/dist/protocol/iq/appstate-sync.js.map +1 -0
- package/dist/protocol/iq/business.d.ts +13 -0
- package/dist/protocol/iq/business.d.ts.map +1 -0
- package/dist/protocol/iq/business.js +64 -0
- package/dist/protocol/iq/business.js.map +1 -0
- package/dist/protocol/iq/dirty-bits.d.ts +8 -0
- package/dist/protocol/iq/dirty-bits.d.ts.map +1 -0
- package/dist/protocol/iq/dirty-bits.js +23 -0
- package/dist/protocol/iq/dirty-bits.js.map +1 -0
- package/dist/protocol/iq/group-ops.d.ts +34 -0
- package/dist/protocol/iq/group-ops.d.ts.map +1 -0
- package/dist/protocol/iq/group-ops.js +164 -0
- package/dist/protocol/iq/group-ops.js.map +1 -0
- package/dist/protocol/iq/newsletter.d.ts +4 -0
- package/dist/protocol/iq/newsletter.d.ts.map +1 -0
- package/dist/protocol/iq/newsletter.js +18 -0
- package/dist/protocol/iq/newsletter.js.map +1 -0
- package/dist/protocol/iq/prekey-fetch.d.ts +18 -0
- package/dist/protocol/iq/prekey-fetch.d.ts.map +1 -0
- package/dist/protocol/iq/prekey-fetch.js +92 -0
- package/dist/protocol/iq/prekey-fetch.js.map +1 -0
- package/dist/protocol/iq/privacy-token.d.ts +9 -0
- package/dist/protocol/iq/privacy-token.d.ts.map +1 -0
- package/dist/protocol/iq/privacy-token.js +30 -0
- package/dist/protocol/iq/privacy-token.js.map +1 -0
- package/dist/protocol/iq/privacy.d.ts +22 -0
- package/dist/protocol/iq/privacy.d.ts.map +1 -0
- package/dist/protocol/iq/privacy.js +133 -0
- package/dist/protocol/iq/privacy.js.map +1 -0
- package/dist/protocol/iq/profile.d.ts +22 -0
- package/dist/protocol/iq/profile.d.ts.map +1 -0
- package/dist/protocol/iq/profile.js +80 -0
- package/dist/protocol/iq/profile.js.map +1 -0
- package/dist/protocol/iq/router.d.ts +39 -0
- package/dist/protocol/iq/router.d.ts.map +1 -0
- package/dist/protocol/iq/router.js +118 -0
- package/dist/protocol/iq/router.js.map +1 -0
- package/dist/protocol/iq/usync.d.ts +8 -0
- package/dist/protocol/iq/usync.d.ts.map +1 -0
- package/dist/protocol/iq/usync.js +68 -0
- package/dist/protocol/iq/usync.js.map +1 -0
- package/dist/protocol/push/app-state-key-share.d.ts +17 -0
- package/dist/protocol/push/app-state-key-share.d.ts.map +1 -0
- package/dist/protocol/push/app-state-key-share.js +30 -0
- package/dist/protocol/push/app-state-key-share.js.map +1 -0
- package/dist/protocol/push/call-failure.d.ts +16 -0
- package/dist/protocol/push/call-failure.d.ts.map +1 -0
- package/dist/protocol/push/call-failure.js +32 -0
- package/dist/protocol/push/call-failure.js.map +1 -0
- package/dist/protocol/push/chatstate.d.ts +15 -0
- package/dist/protocol/push/chatstate.d.ts.map +1 -0
- package/dist/protocol/push/chatstate.js +27 -0
- package/dist/protocol/push/chatstate.js.map +1 -0
- package/dist/protocol/push/error-stanza.d.ts +8 -0
- package/dist/protocol/push/error-stanza.d.ts.map +1 -0
- package/dist/protocol/push/error-stanza.js +17 -0
- package/dist/protocol/push/error-stanza.js.map +1 -0
- package/dist/protocol/push/history-sync.d.ts +46 -0
- package/dist/protocol/push/history-sync.d.ts.map +1 -0
- package/dist/protocol/push/history-sync.js +117 -0
- package/dist/protocol/push/history-sync.js.map +1 -0
- package/dist/protocol/push/message.d.ts +21 -0
- package/dist/protocol/push/message.d.ts.map +1 -0
- package/dist/protocol/push/message.js +42 -0
- package/dist/protocol/push/message.js.map +1 -0
- package/dist/protocol/push/notification.d.ts +21 -0
- package/dist/protocol/push/notification.d.ts.map +1 -0
- package/dist/protocol/push/notification.js +34 -0
- package/dist/protocol/push/notification.js.map +1 -0
- package/dist/protocol/push/presence.d.ts +11 -0
- package/dist/protocol/push/presence.d.ts.map +1 -0
- package/dist/protocol/push/presence.js +18 -0
- package/dist/protocol/push/presence.js.map +1 -0
- package/dist/protocol/push/receipt.d.ts +14 -0
- package/dist/protocol/push/receipt.d.ts.map +1 -0
- package/dist/protocol/push/receipt.js +25 -0
- package/dist/protocol/push/receipt.js.map +1 -0
- package/dist/protocol/signal/fake-app-state-crypto.d.ts +49 -0
- package/dist/protocol/signal/fake-app-state-crypto.d.ts.map +1 -0
- package/dist/protocol/signal/fake-app-state-crypto.js +202 -0
- package/dist/protocol/signal/fake-app-state-crypto.js.map +1 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts +38 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.js +408 -0
- package/dist/protocol/signal/fake-peer-double-ratchet.js.map +1 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts +10 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.js +129 -0
- package/dist/protocol/signal/fake-peer-group-recv-session.js.map +1 -0
- package/dist/protocol/signal/fake-peer-identity.d.ts +7 -0
- package/dist/protocol/signal/fake-peer-identity.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-identity.js +12 -0
- package/dist/protocol/signal/fake-peer-identity.js.map +1 -0
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts +24 -0
- package/dist/protocol/signal/fake-peer-key-bundle.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-key-bundle.js +29 -0
- package/dist/protocol/signal/fake-peer-key-bundle.js.map +1 -0
- package/dist/protocol/signal/fake-peer-recv-session.d.ts +60 -0
- package/dist/protocol/signal/fake-peer-recv-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-recv-session.js +284 -0
- package/dist/protocol/signal/fake-peer-recv-session.js.map +1 -0
- package/dist/protocol/signal/fake-peer-session.d.ts +87 -0
- package/dist/protocol/signal/fake-peer-session.d.ts.map +1 -0
- package/dist/protocol/signal/fake-peer-session.js +207 -0
- package/dist/protocol/signal/fake-peer-session.js.map +1 -0
- package/dist/protocol/signal/fake-sender-key.d.ts +15 -0
- package/dist/protocol/signal/fake-sender-key.d.ts.map +1 -0
- package/dist/protocol/signal/fake-sender-key.js +91 -0
- package/dist/protocol/signal/fake-sender-key.js.map +1 -0
- package/dist/protocol/signal/prekey-upload.d.ts +22 -0
- package/dist/protocol/signal/prekey-upload.d.ts.map +1 -0
- package/dist/protocol/signal/prekey-upload.js +113 -0
- package/dist/protocol/signal/prekey-upload.js.map +1 -0
- package/dist/protocol/stream/stream-error.d.ts +8 -0
- package/dist/protocol/stream/stream-error.d.ts.map +1 -0
- package/dist/protocol/stream/stream-error.js +64 -0
- package/dist/protocol/stream/stream-error.js.map +1 -0
- package/dist/state/fake-app-state-collection.d.ts +35 -0
- package/dist/state/fake-app-state-collection.d.ts.map +1 -0
- package/dist/state/fake-app-state-collection.js +139 -0
- package/dist/state/fake-app-state-collection.js.map +1 -0
- package/dist/state/fake-media-store.d.ts +35 -0
- package/dist/state/fake-media-store.d.ts.map +1 -0
- package/dist/state/fake-media-store.js +57 -0
- package/dist/state/fake-media-store.js.map +1 -0
- package/dist/transport/codec.d.ts +10 -0
- package/dist/transport/codec.d.ts.map +1 -0
- package/dist/transport/codec.js +17 -0
- package/dist/transport/codec.js.map +1 -0
- package/dist/transport/crypto.d.ts +11 -0
- package/dist/transport/crypto.d.ts.map +1 -0
- package/dist/transport/crypto.js +36 -0
- package/dist/transport/crypto.js.map +1 -0
- package/dist/transport/index.d.ts +4 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +20 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/protos.d.ts +10 -0
- package/dist/transport/protos.d.ts.map +1 -0
- package/dist/transport/protos.js +13 -0
- package/dist/transport/protos.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Bidirectional Signal Double Ratchet used by fake peers. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FakePeerDoubleRatchet = exports.FakePeerDoubleRatchetError = void 0;
|
|
5
|
+
const crypto_1 = require("../../transport/crypto");
|
|
6
|
+
const protos_1 = require("../../transport/protos");
|
|
7
|
+
const SIGNAL_VERSION = 3;
|
|
8
|
+
const SIGNAL_MAC_SIZE = 8;
|
|
9
|
+
const SIGNAL_PREFIX_FF = new Uint8Array(32).fill(0xff);
|
|
10
|
+
const MESSAGE_KEY_LABEL = new Uint8Array([1]);
|
|
11
|
+
const CHAIN_KEY_LABEL = new Uint8Array([2]);
|
|
12
|
+
class FakePeerDoubleRatchetError extends Error {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'FakePeerDoubleRatchetError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.FakePeerDoubleRatchetError = FakePeerDoubleRatchetError;
|
|
19
|
+
const MAX_FUTURE_RECV_KEYS = 2000;
|
|
20
|
+
class FakePeerDoubleRatchet {
|
|
21
|
+
constructor(keyBundle) {
|
|
22
|
+
this.remoteIdentityPubSerialized = null;
|
|
23
|
+
this.rootKey = null;
|
|
24
|
+
this.sendChain = null;
|
|
25
|
+
this.recvChain = null;
|
|
26
|
+
this.pendingPreKeyHeader = null;
|
|
27
|
+
this.bootstrapChainKey = null;
|
|
28
|
+
this.hasOutboundSendChain = false;
|
|
29
|
+
this.keyBundle = keyBundle;
|
|
30
|
+
this.localIdentityPubSerialized = (0, crypto_1.toSerializedPubKey)(keyBundle.identityKeyPair.pubKey);
|
|
31
|
+
}
|
|
32
|
+
get registrationId() {
|
|
33
|
+
return this.keyBundle.registrationId;
|
|
34
|
+
}
|
|
35
|
+
hasSendChain() {
|
|
36
|
+
return this.sendChain !== null && this.hasOutboundSendChain;
|
|
37
|
+
}
|
|
38
|
+
async initiateOutbound(bundle, options = {}) {
|
|
39
|
+
if (this.rootKey || this.sendChain || this.recvChain) {
|
|
40
|
+
throw new FakePeerDoubleRatchetError('session already initialized');
|
|
41
|
+
}
|
|
42
|
+
const remoteIdentity = (0, crypto_1.toSerializedPubKey)(bundle.identityKey);
|
|
43
|
+
const remoteSigned = (0, crypto_1.toSerializedPubKey)(bundle.signedPreKey.publicKey);
|
|
44
|
+
const localBase = await crypto_1.X25519.generateKeyPair();
|
|
45
|
+
const localBaseSerialized = (0, crypto_1.toSerializedPubKey)(localBase.pubKey);
|
|
46
|
+
// Do not fallback to bundle.preKeys[0], otherwise concurrent peers reuse one key id.
|
|
47
|
+
const consumedOneTime = options.skipOneTimePreKey ? undefined : options.oneTimePreKey;
|
|
48
|
+
const remoteOneTime = consumedOneTime ? (0, crypto_1.toSerializedPubKey)(consumedOneTime.publicKey) : null;
|
|
49
|
+
const [dh1, dh2, dh3, dh4] = await Promise.all([
|
|
50
|
+
crypto_1.X25519.scalarMult(this.keyBundle.identityKeyPair.privKey, (0, crypto_1.toRawPubKey)(remoteSigned)),
|
|
51
|
+
crypto_1.X25519.scalarMult(localBase.privKey, (0, crypto_1.toRawPubKey)(remoteIdentity)),
|
|
52
|
+
crypto_1.X25519.scalarMult(localBase.privKey, (0, crypto_1.toRawPubKey)(remoteSigned)),
|
|
53
|
+
remoteOneTime
|
|
54
|
+
? crypto_1.X25519.scalarMult(localBase.privKey, (0, crypto_1.toRawPubKey)(remoteOneTime))
|
|
55
|
+
: Promise.resolve(null)
|
|
56
|
+
]);
|
|
57
|
+
const sharedParts = [SIGNAL_PREFIX_FF, dh1, dh2, dh3];
|
|
58
|
+
if (dh4)
|
|
59
|
+
sharedParts.push(dh4);
|
|
60
|
+
const shared = concatBytes(sharedParts);
|
|
61
|
+
const [rootKey, _chainKey] = await (0, crypto_1.hkdfSplit)(shared, null, 'WhisperText');
|
|
62
|
+
void _chainKey;
|
|
63
|
+
const sendRatchet = await crypto_1.X25519.generateKeyPair();
|
|
64
|
+
const ratchetSecret = await crypto_1.X25519.scalarMult(sendRatchet.privKey, (0, crypto_1.toRawPubKey)(remoteSigned));
|
|
65
|
+
const [nextRootKey, sendChainKey] = await (0, crypto_1.hkdfSplit)(ratchetSecret, rootKey, 'WhisperRatchet');
|
|
66
|
+
this.rootKey = nextRootKey;
|
|
67
|
+
this.remoteIdentityPubSerialized = remoteIdentity;
|
|
68
|
+
this.sendChain = {
|
|
69
|
+
ratchetKeyPair: sendRatchet,
|
|
70
|
+
ratchetPubSerialized: (0, crypto_1.toSerializedPubKey)(sendRatchet.pubKey),
|
|
71
|
+
chainKey: sendChainKey,
|
|
72
|
+
nextIndex: 0
|
|
73
|
+
};
|
|
74
|
+
this.hasOutboundSendChain = true;
|
|
75
|
+
this.pendingPreKeyHeader = {
|
|
76
|
+
preKeyId: consumedOneTime?.keyId,
|
|
77
|
+
signedPreKeyId: bundle.signedPreKey.keyId,
|
|
78
|
+
baseKey: localBaseSerialized
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
async encrypt(plaintext) {
|
|
82
|
+
if (!this.sendChain) {
|
|
83
|
+
throw new FakePeerDoubleRatchetError('cannot encrypt: session has no send chain (call initiateOutbound first)');
|
|
84
|
+
}
|
|
85
|
+
if (!this.remoteIdentityPubSerialized) {
|
|
86
|
+
throw new FakePeerDoubleRatchetError('remote identity not set');
|
|
87
|
+
}
|
|
88
|
+
const { nextChainKey, messageKey } = await deriveMessageKey(this.sendChain.nextIndex, this.sendChain.chainKey);
|
|
89
|
+
const [cipherKey, macKey] = await Promise.all([
|
|
90
|
+
(0, crypto_1.importAesCbcKey)(messageKey.cipherKey),
|
|
91
|
+
(0, crypto_1.importHmacKey)(messageKey.macKey)
|
|
92
|
+
]);
|
|
93
|
+
const ciphertext = await (0, crypto_1.aesCbcEncrypt)(cipherKey, messageKey.iv, plaintext);
|
|
94
|
+
const signalPayload = protos_1.proto.SignalMessage.encode({
|
|
95
|
+
ratchetKey: this.sendChain.ratchetPubSerialized,
|
|
96
|
+
counter: messageKey.index,
|
|
97
|
+
previousCounter: 0,
|
|
98
|
+
ciphertext
|
|
99
|
+
}).finish();
|
|
100
|
+
const versioned = (0, crypto_1.prependVersion)(signalPayload, SIGNAL_VERSION);
|
|
101
|
+
const macInput = concatBytes([
|
|
102
|
+
this.localIdentityPubSerialized,
|
|
103
|
+
this.remoteIdentityPubSerialized,
|
|
104
|
+
versioned
|
|
105
|
+
]);
|
|
106
|
+
const fullMac = await (0, crypto_1.hmacSign)(macKey, macInput);
|
|
107
|
+
const mac = fullMac.subarray(0, SIGNAL_MAC_SIZE);
|
|
108
|
+
const inner = concatBytes([versioned, mac]);
|
|
109
|
+
this.sendChain = {
|
|
110
|
+
...this.sendChain,
|
|
111
|
+
chainKey: nextChainKey,
|
|
112
|
+
nextIndex: messageKey.index + 1
|
|
113
|
+
};
|
|
114
|
+
if (this.pendingPreKeyHeader) {
|
|
115
|
+
const header = this.pendingPreKeyHeader;
|
|
116
|
+
this.pendingPreKeyHeader = null;
|
|
117
|
+
const preKeyMessage = protos_1.proto.PreKeySignalMessage.encode({
|
|
118
|
+
registrationId: this.keyBundle.registrationId,
|
|
119
|
+
preKeyId: header.preKeyId,
|
|
120
|
+
signedPreKeyId: header.signedPreKeyId,
|
|
121
|
+
baseKey: header.baseKey,
|
|
122
|
+
identityKey: this.localIdentityPubSerialized,
|
|
123
|
+
message: inner
|
|
124
|
+
}).finish();
|
|
125
|
+
return {
|
|
126
|
+
type: 'pkmsg',
|
|
127
|
+
ciphertext: (0, crypto_1.prependVersion)(preKeyMessage, SIGNAL_VERSION)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return { type: 'msg', ciphertext: inner };
|
|
131
|
+
}
|
|
132
|
+
async decryptPreKeyMessage(envelope) {
|
|
133
|
+
const body = readVersionedBody(envelope);
|
|
134
|
+
const preKeyMessage = protos_1.proto.PreKeySignalMessage.decode(body);
|
|
135
|
+
const baseKey = requireBytes(preKeyMessage.baseKey, 'baseKey');
|
|
136
|
+
const remoteIdentity = requireBytes(preKeyMessage.identityKey, 'identityKey');
|
|
137
|
+
const innerMessage = requireBytes(preKeyMessage.message, 'message');
|
|
138
|
+
const signedPreKeyId = preKeyMessage.signedPreKeyId;
|
|
139
|
+
if (signedPreKeyId === null || signedPreKeyId === undefined) {
|
|
140
|
+
throw new FakePeerDoubleRatchetError('PreKeySignalMessage missing signedPreKeyId');
|
|
141
|
+
}
|
|
142
|
+
if (signedPreKeyId !== this.keyBundle.signedPreKey.id) {
|
|
143
|
+
throw new FakePeerDoubleRatchetError(`signedPreKeyId mismatch: got ${signedPreKeyId}, expected ${this.keyBundle.signedPreKey.id}`);
|
|
144
|
+
}
|
|
145
|
+
const oneTimePreKeyId = preKeyMessage.preKeyId;
|
|
146
|
+
let oneTimePrivKey = null;
|
|
147
|
+
if (oneTimePreKeyId !== null && oneTimePreKeyId !== undefined) {
|
|
148
|
+
const entry = this.keyBundle.oneTimePreKeys.find((k) => k.id === oneTimePreKeyId);
|
|
149
|
+
if (!entry) {
|
|
150
|
+
throw new FakePeerDoubleRatchetError(`unknown one-time preKeyId ${oneTimePreKeyId}`);
|
|
151
|
+
}
|
|
152
|
+
oneTimePrivKey = entry.keyPair.privKey;
|
|
153
|
+
}
|
|
154
|
+
const remoteIdentityRaw = (0, crypto_1.toRawPubKey)(remoteIdentity);
|
|
155
|
+
const baseKeyRaw = (0, crypto_1.toRawPubKey)(baseKey);
|
|
156
|
+
const signedPriv = this.keyBundle.signedPreKey.keyPair.privKey;
|
|
157
|
+
const identityPriv = this.keyBundle.identityKeyPair.privKey;
|
|
158
|
+
const [dh1, dh2, dh3, dh4] = await Promise.all([
|
|
159
|
+
crypto_1.X25519.scalarMult(signedPriv, remoteIdentityRaw),
|
|
160
|
+
crypto_1.X25519.scalarMult(identityPriv, baseKeyRaw),
|
|
161
|
+
crypto_1.X25519.scalarMult(signedPriv, baseKeyRaw),
|
|
162
|
+
oneTimePrivKey
|
|
163
|
+
? crypto_1.X25519.scalarMult(oneTimePrivKey, baseKeyRaw)
|
|
164
|
+
: Promise.resolve(null)
|
|
165
|
+
]);
|
|
166
|
+
const sharedParts = [SIGNAL_PREFIX_FF, dh1, dh2, dh3];
|
|
167
|
+
if (dh4)
|
|
168
|
+
sharedParts.push(dh4);
|
|
169
|
+
const shared = concatBytes(sharedParts);
|
|
170
|
+
const [rootKey, chainKey] = await (0, crypto_1.hkdfSplit)(shared, null, 'WhisperText');
|
|
171
|
+
this.remoteIdentityPubSerialized = (0, crypto_1.toSerializedPubKey)(remoteIdentity);
|
|
172
|
+
this.rootKey = rootKey;
|
|
173
|
+
this.bootstrapChainKey = chainKey;
|
|
174
|
+
return this.decryptInnerSignalMessage(innerMessage, /* isBootstrap */ true);
|
|
175
|
+
}
|
|
176
|
+
async decryptMessage(envelope) {
|
|
177
|
+
return this.decryptInnerSignalMessage(envelope, /* isBootstrap */ false);
|
|
178
|
+
}
|
|
179
|
+
async decryptInnerSignalMessage(signalMessageBytes, isBootstrap) {
|
|
180
|
+
if (signalMessageBytes.byteLength < 1 + SIGNAL_MAC_SIZE) {
|
|
181
|
+
throw new FakePeerDoubleRatchetError('signal message too short');
|
|
182
|
+
}
|
|
183
|
+
const versionByte = signalMessageBytes[0];
|
|
184
|
+
if (versionByte >>> 4 !== SIGNAL_VERSION) {
|
|
185
|
+
throw new FakePeerDoubleRatchetError(`unsupported signal version ${versionByte >>> 4}`);
|
|
186
|
+
}
|
|
187
|
+
const macStart = signalMessageBytes.byteLength - SIGNAL_MAC_SIZE;
|
|
188
|
+
const versionedBody = signalMessageBytes.subarray(0, macStart);
|
|
189
|
+
const macBytes = signalMessageBytes.subarray(macStart);
|
|
190
|
+
const protoBody = versionedBody.subarray(1);
|
|
191
|
+
const signalMessage = protos_1.proto.SignalMessage.decode(protoBody);
|
|
192
|
+
const ratchetKey = requireBytes(signalMessage.ratchetKey, 'ratchetKey');
|
|
193
|
+
const counter = signalMessage.counter;
|
|
194
|
+
if (counter === null || counter === undefined) {
|
|
195
|
+
throw new FakePeerDoubleRatchetError('SignalMessage missing counter');
|
|
196
|
+
}
|
|
197
|
+
const ciphertext = requireBytes(signalMessage.ciphertext, 'ciphertext');
|
|
198
|
+
const ratchetSerialized = (0, crypto_1.toSerializedPubKey)(ratchetKey);
|
|
199
|
+
if (isBootstrap) {
|
|
200
|
+
if (!this.rootKey || !this.bootstrapChainKey) {
|
|
201
|
+
throw new FakePeerDoubleRatchetError('bootstrap state missing');
|
|
202
|
+
}
|
|
203
|
+
const ratchetShared = await crypto_1.X25519.scalarMult(this.keyBundle.signedPreKey.keyPair.privKey, (0, crypto_1.toRawPubKey)(ratchetKey));
|
|
204
|
+
const [nextRootKey, recvChainKey] = await (0, crypto_1.hkdfSplit)(ratchetShared, this.rootKey, 'WhisperRatchet');
|
|
205
|
+
this.rootKey = nextRootKey;
|
|
206
|
+
this.bootstrapChainKey = null;
|
|
207
|
+
this.recvChain = {
|
|
208
|
+
ratchetPubKey: ratchetSerialized,
|
|
209
|
+
chainKey: recvChainKey,
|
|
210
|
+
nextIndex: 0,
|
|
211
|
+
unusedKeys: []
|
|
212
|
+
};
|
|
213
|
+
await this.rotateSendRatchet(ratchetKey);
|
|
214
|
+
}
|
|
215
|
+
else if (!this.recvChain ||
|
|
216
|
+
!uint8Equal(this.recvChain.ratchetPubKey, ratchetSerialized)) {
|
|
217
|
+
await this.runRecvRatchetStep(ratchetKey);
|
|
218
|
+
}
|
|
219
|
+
if (!this.recvChain) {
|
|
220
|
+
throw new FakePeerDoubleRatchetError('recv chain not initialized');
|
|
221
|
+
}
|
|
222
|
+
let messageKey = null;
|
|
223
|
+
if (counter < this.recvChain.nextIndex) {
|
|
224
|
+
const stashedIndex = this.recvChain.unusedKeys.findIndex((entry) => entry.index === counter);
|
|
225
|
+
if (stashedIndex === -1) {
|
|
226
|
+
throw new FakePeerDoubleRatchetError(`recv counter ${counter} is stale (next=${this.recvChain.nextIndex})`);
|
|
227
|
+
}
|
|
228
|
+
const stashed = this.recvChain.unusedKeys[stashedIndex];
|
|
229
|
+
messageKey = {
|
|
230
|
+
cipherKey: stashed.cipherKey,
|
|
231
|
+
macKey: stashed.macKey,
|
|
232
|
+
iv: stashed.iv
|
|
233
|
+
};
|
|
234
|
+
this.recvChain = {
|
|
235
|
+
ratchetPubKey: this.recvChain.ratchetPubKey,
|
|
236
|
+
chainKey: this.recvChain.chainKey,
|
|
237
|
+
nextIndex: this.recvChain.nextIndex,
|
|
238
|
+
unusedKeys: this.recvChain.unusedKeys.filter((_, i) => i !== stashedIndex)
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
const skipDistance = counter - this.recvChain.nextIndex;
|
|
243
|
+
if (skipDistance > MAX_FUTURE_RECV_KEYS) {
|
|
244
|
+
throw new FakePeerDoubleRatchetError(`recv counter ${counter} is too far in the future (skip=${skipDistance})`);
|
|
245
|
+
}
|
|
246
|
+
let chainKey = this.recvChain.chainKey;
|
|
247
|
+
const newlyStashed = [];
|
|
248
|
+
let walkIndex = this.recvChain.nextIndex;
|
|
249
|
+
while (walkIndex <= counter) {
|
|
250
|
+
const derived = await deriveMessageKeyFromChain(chainKey);
|
|
251
|
+
chainKey = derived.nextChainKey;
|
|
252
|
+
if (walkIndex === counter) {
|
|
253
|
+
messageKey = derived.messageKey;
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
newlyStashed.push({
|
|
257
|
+
index: walkIndex,
|
|
258
|
+
cipherKey: derived.messageKey.cipherKey,
|
|
259
|
+
macKey: derived.messageKey.macKey,
|
|
260
|
+
iv: derived.messageKey.iv
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
walkIndex += 1;
|
|
264
|
+
}
|
|
265
|
+
const allUnused = [...this.recvChain.unusedKeys, ...newlyStashed];
|
|
266
|
+
const trimmed = allUnused.length > MAX_FUTURE_RECV_KEYS
|
|
267
|
+
? allUnused.slice(allUnused.length - MAX_FUTURE_RECV_KEYS)
|
|
268
|
+
: allUnused;
|
|
269
|
+
this.recvChain = {
|
|
270
|
+
ratchetPubKey: this.recvChain.ratchetPubKey,
|
|
271
|
+
chainKey,
|
|
272
|
+
nextIndex: walkIndex,
|
|
273
|
+
unusedKeys: trimmed
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
if (!messageKey) {
|
|
277
|
+
throw new FakePeerDoubleRatchetError('failed to derive recv message key');
|
|
278
|
+
}
|
|
279
|
+
if (!this.remoteIdentityPubSerialized) {
|
|
280
|
+
throw new FakePeerDoubleRatchetError('remoteIdentityPub not set');
|
|
281
|
+
}
|
|
282
|
+
const macInput = concatBytes([
|
|
283
|
+
this.remoteIdentityPubSerialized,
|
|
284
|
+
this.localIdentityPubSerialized,
|
|
285
|
+
versionedBody
|
|
286
|
+
]);
|
|
287
|
+
const macKeyHandle = await (0, crypto_1.importHmacKey)(messageKey.macKey);
|
|
288
|
+
const expectedFullMac = await (0, crypto_1.hmacSign)(macKeyHandle, macInput);
|
|
289
|
+
const expectedMac = expectedFullMac.subarray(0, SIGNAL_MAC_SIZE);
|
|
290
|
+
if (!uint8Equal(expectedMac, macBytes)) {
|
|
291
|
+
throw new FakePeerDoubleRatchetError('signal message MAC mismatch');
|
|
292
|
+
}
|
|
293
|
+
const cipherKeyHandle = await (0, crypto_1.importAesCbcKey)(messageKey.cipherKey);
|
|
294
|
+
const padded = await (0, crypto_1.aesCbcDecrypt)(cipherKeyHandle, messageKey.iv, ciphertext);
|
|
295
|
+
return unpadPkcs7(padded);
|
|
296
|
+
}
|
|
297
|
+
async runRecvRatchetStep(remoteRatchetPub) {
|
|
298
|
+
if (!this.rootKey) {
|
|
299
|
+
throw new FakePeerDoubleRatchetError('cannot run recv DR step: no root key');
|
|
300
|
+
}
|
|
301
|
+
if (!this.sendChain) {
|
|
302
|
+
throw new FakePeerDoubleRatchetError('cannot run recv DR step: no current local ratchet (alice has not initiated)');
|
|
303
|
+
}
|
|
304
|
+
const remoteRatchetRaw = (0, crypto_1.toRawPubKey)(remoteRatchetPub);
|
|
305
|
+
const ratchetShared = await crypto_1.X25519.scalarMult(this.sendChain.ratchetKeyPair.privKey, remoteRatchetRaw);
|
|
306
|
+
const [nextRootKey, recvChainKey] = await (0, crypto_1.hkdfSplit)(ratchetShared, this.rootKey, 'WhisperRatchet');
|
|
307
|
+
this.rootKey = nextRootKey;
|
|
308
|
+
this.recvChain = {
|
|
309
|
+
ratchetPubKey: (0, crypto_1.toSerializedPubKey)(remoteRatchetPub),
|
|
310
|
+
chainKey: recvChainKey,
|
|
311
|
+
nextIndex: 0,
|
|
312
|
+
unusedKeys: []
|
|
313
|
+
};
|
|
314
|
+
await this.rotateSendRatchet(remoteRatchetPub);
|
|
315
|
+
}
|
|
316
|
+
async rotateSendRatchet(remoteRatchetPub) {
|
|
317
|
+
if (!this.rootKey) {
|
|
318
|
+
throw new FakePeerDoubleRatchetError('cannot rotate send ratchet: no root key');
|
|
319
|
+
}
|
|
320
|
+
const newRatchet = await crypto_1.X25519.generateKeyPair();
|
|
321
|
+
const ratchetShared = await crypto_1.X25519.scalarMult(newRatchet.privKey, (0, crypto_1.toRawPubKey)(remoteRatchetPub));
|
|
322
|
+
const [nextRootKey, sendChainKey] = await (0, crypto_1.hkdfSplit)(ratchetShared, this.rootKey, 'WhisperRatchet');
|
|
323
|
+
this.rootKey = nextRootKey;
|
|
324
|
+
this.sendChain = {
|
|
325
|
+
ratchetKeyPair: newRatchet,
|
|
326
|
+
ratchetPubSerialized: (0, crypto_1.toSerializedPubKey)(newRatchet.pubKey),
|
|
327
|
+
chainKey: sendChainKey,
|
|
328
|
+
nextIndex: 0
|
|
329
|
+
};
|
|
330
|
+
this.hasOutboundSendChain = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
exports.FakePeerDoubleRatchet = FakePeerDoubleRatchet;
|
|
334
|
+
async function deriveMessageKey(index, chainKey) {
|
|
335
|
+
const hmacKey = await (0, crypto_1.importHmacKey)(chainKey);
|
|
336
|
+
const [messageInputKey, nextChainRaw] = await Promise.all([
|
|
337
|
+
(0, crypto_1.hmacSign)(hmacKey, MESSAGE_KEY_LABEL),
|
|
338
|
+
(0, crypto_1.hmacSign)(hmacKey, CHAIN_KEY_LABEL)
|
|
339
|
+
]);
|
|
340
|
+
const expanded = await (0, crypto_1.hkdf)(messageInputKey, null, 'WhisperMessageKeys', 80);
|
|
341
|
+
return {
|
|
342
|
+
nextChainKey: nextChainRaw.subarray(0, 32),
|
|
343
|
+
messageKey: {
|
|
344
|
+
index,
|
|
345
|
+
cipherKey: expanded.subarray(0, 32),
|
|
346
|
+
macKey: expanded.subarray(32, 64),
|
|
347
|
+
iv: expanded.subarray(64, 80)
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
async function deriveMessageKeyFromChain(chainKey) {
|
|
352
|
+
const result = await deriveMessageKey(0, chainKey);
|
|
353
|
+
return {
|
|
354
|
+
nextChainKey: result.nextChainKey,
|
|
355
|
+
messageKey: {
|
|
356
|
+
cipherKey: result.messageKey.cipherKey,
|
|
357
|
+
macKey: result.messageKey.macKey,
|
|
358
|
+
iv: result.messageKey.iv
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function readVersionedBody(envelope) {
|
|
363
|
+
if (envelope.byteLength < 1) {
|
|
364
|
+
throw new FakePeerDoubleRatchetError('signal envelope is empty');
|
|
365
|
+
}
|
|
366
|
+
const version = envelope[0] >>> 4;
|
|
367
|
+
if (version !== SIGNAL_VERSION) {
|
|
368
|
+
throw new FakePeerDoubleRatchetError(`unsupported signal version ${version}`);
|
|
369
|
+
}
|
|
370
|
+
return envelope.subarray(1);
|
|
371
|
+
}
|
|
372
|
+
function unpadPkcs7(padded) {
|
|
373
|
+
if (padded.byteLength === 0)
|
|
374
|
+
return padded;
|
|
375
|
+
const padLen = padded[padded.byteLength - 1];
|
|
376
|
+
if (padLen === 0 || padLen > 16)
|
|
377
|
+
return padded;
|
|
378
|
+
if (padLen > padded.byteLength)
|
|
379
|
+
return padded;
|
|
380
|
+
return padded.subarray(0, padded.byteLength - padLen);
|
|
381
|
+
}
|
|
382
|
+
function uint8Equal(a, b) {
|
|
383
|
+
if (a.byteLength !== b.byteLength)
|
|
384
|
+
return false;
|
|
385
|
+
for (let i = 0; i < a.byteLength; i += 1) {
|
|
386
|
+
if (a[i] !== b[i])
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
function concatBytes(parts) {
|
|
392
|
+
let total = 0;
|
|
393
|
+
for (const p of parts)
|
|
394
|
+
total += p.byteLength;
|
|
395
|
+
const out = new Uint8Array(total);
|
|
396
|
+
let offset = 0;
|
|
397
|
+
for (const p of parts) {
|
|
398
|
+
out.set(p, offset);
|
|
399
|
+
offset += p.byteLength;
|
|
400
|
+
}
|
|
401
|
+
return out;
|
|
402
|
+
}
|
|
403
|
+
function requireBytes(value, label) {
|
|
404
|
+
if (!value)
|
|
405
|
+
throw new FakePeerDoubleRatchetError(`${label} missing`);
|
|
406
|
+
return value;
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=fake-peer-double-ratchet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-double-ratchet.js","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-double-ratchet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Receiver-side SenderKey session for group `skmsg` decrypt. */
|
|
2
|
+
export declare class FakePeerGroupRecvSessionError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
export declare class FakePeerGroupRecvSession {
|
|
6
|
+
private readonly records;
|
|
7
|
+
addDistribution(groupId: string, senderJid: string, axolotlBytes: Uint8Array): void;
|
|
8
|
+
decryptGroupMessage(groupId: string, senderJid: string, skmsgBytes: Uint8Array): Promise<Uint8Array>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=fake-peer-group-recv-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-group-recv-session.d.ts","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-group-recv-session.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAoBjE,qBAAa,6BAA8B,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAIrC;AASD,qBAAa,wBAAwB;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IAE1D,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,GAAG,IAAI;IAiC7E,mBAAmB,CAC5B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,UAAU,GACvB,OAAO,CAAC,UAAU,CAAC;CAkFzB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Receiver-side SenderKey session for group `skmsg` decrypt. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FakePeerGroupRecvSession = exports.FakePeerGroupRecvSessionError = void 0;
|
|
5
|
+
const crypto_1 = require("../../transport/crypto");
|
|
6
|
+
const protos_1 = require("../../transport/protos");
|
|
7
|
+
const SIGNAL_GROUP_VERSION = 3;
|
|
8
|
+
const SIGNAL_SIGNATURE_LENGTH = 64;
|
|
9
|
+
const MESSAGE_KEY_LABEL = new Uint8Array([1]);
|
|
10
|
+
const CHAIN_KEY_LABEL = new Uint8Array([2]);
|
|
11
|
+
const WHISPER_GROUP_INFO = 'WhisperGroup';
|
|
12
|
+
class FakePeerGroupRecvSessionError extends Error {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'FakePeerGroupRecvSessionError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.FakePeerGroupRecvSessionError = FakePeerGroupRecvSessionError;
|
|
19
|
+
class FakePeerGroupRecvSession {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.records = new Map();
|
|
22
|
+
}
|
|
23
|
+
addDistribution(groupId, senderJid, axolotlBytes) {
|
|
24
|
+
if (axolotlBytes.byteLength < 1) {
|
|
25
|
+
throw new FakePeerGroupRecvSessionError('SKDM payload empty');
|
|
26
|
+
}
|
|
27
|
+
const version = axolotlBytes[0] >>> 4;
|
|
28
|
+
if (version !== SIGNAL_GROUP_VERSION) {
|
|
29
|
+
throw new FakePeerGroupRecvSessionError(`unsupported SKDM version ${version}`);
|
|
30
|
+
}
|
|
31
|
+
const body = axolotlBytes.subarray(1);
|
|
32
|
+
const decoded = protos_1.proto.SenderKeyDistributionMessage.decode(body);
|
|
33
|
+
if (decoded.id === null ||
|
|
34
|
+
decoded.id === undefined ||
|
|
35
|
+
decoded.iteration === null ||
|
|
36
|
+
decoded.iteration === undefined ||
|
|
37
|
+
!decoded.chainKey ||
|
|
38
|
+
!decoded.signingKey) {
|
|
39
|
+
throw new FakePeerGroupRecvSessionError('invalid SKDM');
|
|
40
|
+
}
|
|
41
|
+
if (decoded.chainKey.byteLength !== 32) {
|
|
42
|
+
throw new FakePeerGroupRecvSessionError(`SKDM chainKey must be 32 bytes, got ${decoded.chainKey.byteLength}`);
|
|
43
|
+
}
|
|
44
|
+
this.records.set(recordKey(groupId, senderJid), {
|
|
45
|
+
keyId: decoded.id,
|
|
46
|
+
nextIteration: decoded.iteration,
|
|
47
|
+
chainKey: decoded.chainKey,
|
|
48
|
+
signingPublicKey: (0, crypto_1.toSerializedPubKey)(decoded.signingKey)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async decryptGroupMessage(groupId, senderJid, skmsgBytes) {
|
|
52
|
+
const record = this.records.get(recordKey(groupId, senderJid));
|
|
53
|
+
if (!record) {
|
|
54
|
+
throw new FakePeerGroupRecvSessionError(`no senderkey state for group=${groupId} sender=${senderJid}`);
|
|
55
|
+
}
|
|
56
|
+
if (skmsgBytes.byteLength < 1 + SIGNAL_SIGNATURE_LENGTH) {
|
|
57
|
+
throw new FakePeerGroupRecvSessionError('skmsg too short');
|
|
58
|
+
}
|
|
59
|
+
const versionByte = skmsgBytes[0];
|
|
60
|
+
if (versionByte >>> 4 !== SIGNAL_GROUP_VERSION) {
|
|
61
|
+
throw new FakePeerGroupRecvSessionError(`unsupported skmsg version ${versionByte >>> 4}`);
|
|
62
|
+
}
|
|
63
|
+
const sigStart = skmsgBytes.byteLength - SIGNAL_SIGNATURE_LENGTH;
|
|
64
|
+
// xeddsaVerify mutates the signature buffer; isolate with copies.
|
|
65
|
+
const versionedContent = skmsgBytes.subarray(0, sigStart).slice();
|
|
66
|
+
const signature = skmsgBytes.subarray(sigStart).slice();
|
|
67
|
+
const protoBody = versionedContent.subarray(1);
|
|
68
|
+
const decoded = protos_1.proto.SenderKeyMessage.decode(protoBody);
|
|
69
|
+
if (decoded.id === null ||
|
|
70
|
+
decoded.id === undefined ||
|
|
71
|
+
decoded.iteration === null ||
|
|
72
|
+
decoded.iteration === undefined ||
|
|
73
|
+
!decoded.ciphertext) {
|
|
74
|
+
throw new FakePeerGroupRecvSessionError('invalid SenderKeyMessage');
|
|
75
|
+
}
|
|
76
|
+
if (decoded.id !== record.keyId) {
|
|
77
|
+
throw new FakePeerGroupRecvSessionError(`senderKey id mismatch: got ${decoded.id}, expected ${record.keyId}`);
|
|
78
|
+
}
|
|
79
|
+
const validSignature = await (0, crypto_1.xeddsaVerify)((0, crypto_1.toRawPubKey)(record.signingPublicKey), versionedContent, signature);
|
|
80
|
+
if (!validSignature) {
|
|
81
|
+
throw new FakePeerGroupRecvSessionError('invalid sender key signature');
|
|
82
|
+
}
|
|
83
|
+
const targetIteration = decoded.iteration;
|
|
84
|
+
if (targetIteration < record.nextIteration) {
|
|
85
|
+
throw new FakePeerGroupRecvSessionError(`out-of-order skmsg iteration ${targetIteration} < ${record.nextIteration}`);
|
|
86
|
+
}
|
|
87
|
+
let chainKey = record.chainKey;
|
|
88
|
+
let seed = null;
|
|
89
|
+
let iteration = record.nextIteration;
|
|
90
|
+
while (iteration <= targetIteration) {
|
|
91
|
+
const hmacKeyHandle = await (0, crypto_1.importHmacKey)(chainKey);
|
|
92
|
+
const [nextChainRaw, messageInputKey] = await Promise.all([
|
|
93
|
+
(0, crypto_1.hmacSign)(hmacKeyHandle, CHAIN_KEY_LABEL),
|
|
94
|
+
(0, crypto_1.hmacSign)(hmacKeyHandle, MESSAGE_KEY_LABEL)
|
|
95
|
+
]);
|
|
96
|
+
const messageSeed = await (0, crypto_1.hkdf)(messageInputKey, null, WHISPER_GROUP_INFO, 50);
|
|
97
|
+
if (iteration === targetIteration) {
|
|
98
|
+
seed = messageSeed;
|
|
99
|
+
}
|
|
100
|
+
chainKey = nextChainRaw.subarray(0, 32);
|
|
101
|
+
iteration += 1;
|
|
102
|
+
}
|
|
103
|
+
if (!seed) {
|
|
104
|
+
throw new FakePeerGroupRecvSessionError('failed to derive message seed');
|
|
105
|
+
}
|
|
106
|
+
record.chainKey = chainKey;
|
|
107
|
+
record.nextIteration = iteration;
|
|
108
|
+
const iv = seed.subarray(0, 16);
|
|
109
|
+
const keyBytes = seed.subarray(16, 48);
|
|
110
|
+
const cipherKey = await (0, crypto_1.importAesCbcKey)(keyBytes);
|
|
111
|
+
const padded = await (0, crypto_1.aesCbcDecrypt)(cipherKey, iv, decoded.ciphertext);
|
|
112
|
+
return unpadPkcs7(padded);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.FakePeerGroupRecvSession = FakePeerGroupRecvSession;
|
|
116
|
+
function recordKey(groupId, senderJid) {
|
|
117
|
+
return `${groupId}\u0000${senderJid}`;
|
|
118
|
+
}
|
|
119
|
+
function unpadPkcs7(padded) {
|
|
120
|
+
if (padded.byteLength === 0)
|
|
121
|
+
return padded;
|
|
122
|
+
const padLen = padded[padded.byteLength - 1];
|
|
123
|
+
if (padLen === 0 || padLen > 16)
|
|
124
|
+
return padded;
|
|
125
|
+
if (padLen > padded.byteLength)
|
|
126
|
+
return padded;
|
|
127
|
+
return padded.subarray(0, padded.byteLength - padLen);
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=fake-peer-group-recv-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-group-recv-session.js","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-group-recv-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SignalKeyPair } from '../../transport/crypto';
|
|
2
|
+
export interface FakePeerIdentity {
|
|
3
|
+
readonly identityKeyPair: SignalKeyPair;
|
|
4
|
+
readonly registrationId: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateFakePeerIdentity(): Promise<FakePeerIdentity>;
|
|
7
|
+
//# sourceMappingURL=fake-peer-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-identity.d.ts","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAU,MAAM,wBAAwB,CAAA;AAEnE,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAA;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAClC;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAM1E"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateFakePeerIdentity = generateFakePeerIdentity;
|
|
4
|
+
const crypto_1 = require("../../transport/crypto");
|
|
5
|
+
async function generateFakePeerIdentity() {
|
|
6
|
+
const identityKeyPair = await crypto_1.X25519.generateKeyPair();
|
|
7
|
+
return {
|
|
8
|
+
identityKeyPair,
|
|
9
|
+
registrationId: Math.floor(Math.random() * 0x3fff) + 1
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=fake-peer-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-identity.js","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-identity.ts"],"names":[],"mappings":";;AAOA,4DAMC;AAbD,mDAAmE;AAO5D,KAAK,UAAU,wBAAwB;IAC1C,MAAM,eAAe,GAAG,MAAM,eAAM,CAAC,eAAe,EAAE,CAAA;IACtD,OAAO;QACH,eAAe;QACf,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC;KACzD,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Generates Signal prekey bundles for fake peers. */
|
|
2
|
+
import { type SignalKeyPair } from '../../transport/crypto';
|
|
3
|
+
export interface FakePeerKeyBundle {
|
|
4
|
+
readonly registrationId: number;
|
|
5
|
+
readonly identityKeyPair: SignalKeyPair;
|
|
6
|
+
readonly signedPreKey: {
|
|
7
|
+
readonly id: number;
|
|
8
|
+
readonly keyPair: SignalKeyPair;
|
|
9
|
+
readonly signature: Uint8Array;
|
|
10
|
+
};
|
|
11
|
+
readonly oneTimePreKeys: ReadonlyArray<{
|
|
12
|
+
readonly id: number;
|
|
13
|
+
readonly keyPair: SignalKeyPair;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
export interface GenerateFakePeerKeyBundleOptions {
|
|
17
|
+
readonly oneTimePreKeyCount?: number;
|
|
18
|
+
readonly identityKeyPair?: SignalKeyPair;
|
|
19
|
+
readonly registrationId?: number;
|
|
20
|
+
readonly signedPreKeyId?: number;
|
|
21
|
+
readonly firstOneTimePreKeyId?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function generateFakePeerKeyBundle(options?: GenerateFakePeerKeyBundleOptions): Promise<FakePeerKeyBundle>;
|
|
24
|
+
//# sourceMappingURL=fake-peer-key-bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-peer-key-bundle.d.ts","sourceRoot":"","sources":["../../../src/protocol/signal/fake-peer-key-bundle.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,OAAO,EAAE,KAAK,aAAa,EAA0C,MAAM,wBAAwB,CAAA;AAEnG,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAA;IACvC,QAAQ,CAAC,YAAY,EAAE;QACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;QAC/B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;KACjC,CAAA;IACD,QAAQ,CAAC,cAAc,EAAE,aAAa,CAAC;QACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;KAClC,CAAC,CAAA;CACL;AAED,MAAM,WAAW,gCAAgC;IAC7C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IACpC,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAA;IACxC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAA;CACzC;AAED,wBAAsB,yBAAyB,CAC3C,OAAO,GAAE,gCAAqC,GAC/C,OAAO,CAAC,iBAAiB,CAAC,CA0B5B"}
|