zapo-js 0.1.2 → 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 +16 -4
- package/dist/appstate/WaAppStateCrypto.js +50 -42
- package/dist/appstate/WaAppStateSyncClient.js +215 -133
- package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/appstate/index.js +9 -7
- package/dist/appstate/utils.js +0 -5
- package/dist/auth/WaAuthClient.js +55 -57
- package/dist/auth/credentials-flow.js +195 -0
- package/dist/auth/index.js +1 -6
- package/dist/auth/pairing/WaPairingFlow.js +39 -32
- package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +35 -17
- package/dist/client/WaClient.js +338 -174
- package/dist/client/WaClientFactory.js +399 -66
- package/dist/client/connection/WaConnectionManager.js +23 -11
- package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +232 -0
- package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +34 -8
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +341 -118
- package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
- package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
- package/dist/client/coordinators/WaProfileCoordinator.js +214 -0
- package/dist/client/coordinators/WaRetryCoordinator.js +184 -30
- package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +184 -0
- package/dist/client/dirty.js +41 -21
- package/dist/client/events/abprops.js +43 -0
- package/dist/client/events/devices.js +72 -0
- package/dist/client/events/group.js +3 -11
- package/dist/client/events/identity.js +22 -0
- package/dist/client/events/privacy-token.js +38 -0
- package/dist/client/events/registration.js +42 -0
- package/dist/client/history-sync.js +50 -9
- package/dist/client/incoming.js +74 -7
- package/dist/client/mailbox.js +40 -23
- package/dist/client/media.js +243 -0
- package/dist/client/messages.js +245 -92
- package/dist/client/messaging/fanout.js +21 -11
- package/dist/client/messaging/participants.js +6 -4
- package/dist/client/persistence/WriteBehindPersistence.js +129 -0
- package/dist/client/tokens/cs-token.js +50 -0
- package/dist/client/tokens/tc-token.js +25 -0
- package/dist/crypto/core/index.js +5 -2
- package/dist/crypto/core/keys.js +4 -4
- package/dist/crypto/core/nonce.js +2 -0
- package/dist/crypto/core/primitives.js +0 -8
- package/dist/crypto/core/random.js +24 -8
- package/dist/crypto/core/xeddsa.js +57 -0
- package/dist/crypto/curves/X25519.js +43 -6
- package/dist/crypto/curves/constants.js +2 -1
- package/dist/crypto/index.js +3 -0
- package/dist/crypto/math/constants.js +13 -36
- package/dist/crypto/math/edwards.js +171 -44
- package/dist/crypto/math/fe.js +706 -0
- package/dist/crypto/math/mod.js +10 -3
- package/dist/esm/appstate/WaAppStateCrypto.js +40 -32
- package/dist/esm/appstate/WaAppStateSyncClient.js +206 -124
- package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
- package/dist/esm/appstate/index.js +2 -2
- package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
- package/dist/esm/appstate/utils.js +2 -5
- package/dist/esm/auth/WaAuthClient.js +52 -54
- package/dist/esm/auth/credentials-flow.js +190 -0
- package/dist/esm/auth/index.js +0 -2
- package/dist/esm/auth/pairing/WaPairingFlow.js +39 -32
- package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +26 -10
- package/dist/esm/client/WaClient.js +339 -175
- package/dist/esm/client/WaClientFactory.js +401 -68
- package/dist/esm/client/connection/WaConnectionManager.js +23 -11
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +229 -0
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +36 -10
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +337 -114
- package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +211 -0
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +186 -32
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +180 -0
- package/dist/esm/client/dirty.js +41 -21
- package/dist/esm/client/events/abprops.js +40 -0
- package/dist/esm/client/events/devices.js +68 -0
- package/dist/esm/client/events/group.js +3 -11
- package/dist/esm/client/events/identity.js +19 -0
- package/dist/esm/client/events/privacy-token.js +35 -0
- package/dist/esm/client/events/registration.js +39 -0
- package/dist/esm/client/history-sync.js +50 -9
- package/dist/esm/client/incoming.js +74 -8
- package/dist/esm/client/mailbox.js +40 -23
- package/dist/esm/client/media.js +234 -0
- package/dist/esm/client/messages.js +244 -91
- package/dist/esm/client/messaging/fanout.js +22 -12
- package/dist/esm/client/messaging/participants.js +6 -4
- package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
- package/dist/esm/client/tokens/cs-token.js +46 -0
- package/dist/esm/client/tokens/tc-token.js +18 -0
- package/dist/esm/crypto/core/index.js +3 -2
- package/dist/esm/crypto/core/keys.js +1 -1
- package/dist/esm/crypto/core/nonce.js +2 -0
- package/dist/esm/crypto/core/primitives.js +0 -7
- package/dist/esm/crypto/core/random.js +23 -7
- package/dist/esm/crypto/core/xeddsa.js +53 -0
- package/dist/esm/crypto/curves/X25519.js +45 -8
- package/dist/esm/crypto/curves/constants.js +1 -0
- package/dist/esm/crypto/index.js +1 -0
- package/dist/esm/crypto/math/constants.js +12 -35
- package/dist/esm/crypto/math/edwards.js +174 -47
- package/dist/esm/crypto/math/fe.js +691 -0
- package/dist/esm/crypto/math/mod.js +10 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
- package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/esm/infra/perf/PromiseDedup.js +20 -0
- package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
- package/dist/esm/infra/perf/StoreLock.js +80 -0
- package/dist/esm/media/WaMediaCrypto.js +332 -55
- package/dist/esm/media/WaMediaTransferClient.js +69 -220
- package/dist/esm/media/constants.js +4 -1
- package/dist/esm/media/processor.js +1 -0
- package/dist/esm/message/WaMessageClient.js +26 -19
- package/dist/esm/message/addon-crypto.js +130 -3
- package/dist/esm/message/content.js +206 -14
- package/dist/esm/message/icdc.js +76 -0
- package/dist/esm/message/incoming.js +38 -24
- package/dist/esm/message/phash.js +35 -13
- package/dist/esm/message/reporting-token.js +17 -30
- package/dist/esm/message/use-case-secret.js +1 -1
- package/dist/esm/protocol/abprops.js +159 -0
- package/dist/esm/protocol/appstate.js +9 -40
- package/dist/esm/protocol/browser.js +24 -18
- package/dist/esm/protocol/constants.js +8 -4
- package/dist/esm/protocol/defaults.js +6 -0
- package/dist/esm/protocol/email.js +30 -0
- package/dist/esm/protocol/index.js +1 -2
- package/dist/esm/protocol/jid.js +142 -39
- package/dist/esm/protocol/message.js +61 -1
- package/dist/esm/protocol/nodes.js +8 -2
- package/dist/esm/protocol/notification.js +9 -1
- package/dist/esm/protocol/privacy-token.js +17 -0
- package/dist/esm/protocol/privacy.js +55 -0
- package/dist/esm/protocol/stream.js +26 -1
- package/dist/esm/retry/codec.js +216 -0
- package/dist/esm/retry/constants.js +1 -1
- package/dist/esm/retry/index.js +2 -2
- package/dist/esm/retry/parse.js +50 -30
- package/dist/esm/retry/reason.js +1 -1
- package/dist/esm/retry/replay.js +11 -7
- package/dist/esm/retry/tracker.js +50 -12
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +52 -32
- package/dist/esm/signal/api/SignalDigestSyncApi.js +21 -15
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +30 -15
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +19 -8
- package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/esm/signal/api/SignalSessionSyncApi.js +17 -8
- package/dist/esm/signal/api/result-map.js +10 -0
- package/dist/esm/signal/constants.js +0 -4
- package/dist/esm/signal/crypto/WaAdvSignature.js +5 -45
- package/dist/esm/signal/crypto/constants.js +0 -4
- package/dist/esm/signal/{store/sqlite.js → encoding.js} +40 -29
- package/dist/esm/signal/group/SenderKeyChain.js +3 -3
- package/dist/esm/signal/group/SenderKeyCodec.js +8 -8
- package/dist/esm/signal/group/SenderKeyManager.js +131 -109
- package/dist/esm/signal/index.js +1 -0
- package/dist/esm/signal/registration/keygen.js +8 -5
- package/dist/esm/signal/registration/utils.js +3 -2
- package/dist/esm/signal/session/SignalProtocol.js +158 -81
- package/dist/esm/signal/session/SignalRatchet.js +21 -10
- package/dist/esm/signal/session/SignalSerializer.js +5 -6
- package/dist/esm/signal/session/SignalSession.js +11 -9
- package/dist/esm/signal/session/resolver.js +140 -105
- package/dist/esm/store/contracts/identity.store.js +1 -0
- package/dist/esm/store/contracts/message-secret.store.js +1 -0
- package/dist/esm/store/contracts/pre-key.store.js +1 -0
- package/dist/esm/store/contracts/privacy-token.store.js +1 -0
- package/dist/esm/store/contracts/session.store.js +1 -0
- package/dist/esm/store/createStore.js +143 -193
- package/dist/esm/store/index.js +5 -10
- package/dist/esm/store/locks/appstate.lock.js +26 -0
- package/dist/esm/store/locks/auth.lock.js +15 -0
- package/dist/esm/store/locks/contact.lock.js +20 -0
- package/dist/esm/store/locks/device-list.lock.js +20 -0
- package/dist/esm/store/locks/identity.lock.js +16 -0
- package/dist/esm/store/locks/message-secret.lock.js +17 -0
- package/dist/esm/store/locks/message.lock.js +21 -0
- package/dist/esm/store/locks/participants.lock.js +20 -0
- package/dist/esm/store/locks/pre-key.lock.js +27 -0
- package/dist/esm/store/locks/privacy-token.lock.js +18 -0
- package/dist/esm/store/locks/retry.lock.js +29 -0
- package/dist/esm/store/locks/sender-key.lock.js +52 -0
- package/dist/esm/store/locks/session.lock.js +19 -0
- package/dist/esm/store/locks/signal.lock.js +39 -0
- package/dist/esm/store/locks/thread.lock.js +21 -0
- package/dist/esm/store/noop.store.js +21 -1
- package/dist/esm/store/providers/memory/appstate.store.js +22 -24
- package/dist/esm/store/providers/memory/device-list.store.js +13 -5
- package/dist/esm/store/providers/memory/identity.store.js +31 -0
- package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
- package/dist/esm/store/providers/memory/participants.store.js +3 -0
- package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
- package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
- package/dist/esm/store/providers/memory/retry.store.js +99 -10
- package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
- package/dist/esm/store/providers/memory/session.store.js +45 -0
- package/dist/esm/store/providers/memory/signal.store.js +1 -147
- package/dist/esm/transport/WaComms.js +7 -4
- package/dist/esm/transport/WaWebSocket.js +9 -7
- package/dist/esm/transport/binary/constants.js +0 -30
- package/dist/esm/transport/binary/decoder.js +4 -4
- package/dist/esm/transport/binary/encoder.js +8 -15
- package/dist/esm/transport/binary/index.js +0 -1
- package/dist/esm/transport/index.js +6 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +37 -22
- package/dist/esm/transport/node/builders/abprops.js +20 -0
- package/dist/esm/transport/node/builders/business.js +129 -0
- package/dist/esm/transport/node/builders/device.js +11 -0
- package/dist/esm/transport/node/builders/email.js +65 -0
- package/dist/esm/transport/node/builders/global.js +370 -0
- package/dist/esm/transport/node/builders/message.js +63 -239
- package/dist/esm/transport/node/builders/offline.js +14 -0
- package/dist/esm/transport/node/builders/pairing.js +0 -24
- package/dist/esm/transport/node/builders/prekeys.js +37 -40
- package/dist/esm/transport/node/builders/presence.js +13 -0
- package/dist/esm/transport/node/builders/privacy-token.js +37 -0
- package/dist/esm/transport/node/builders/privacy.js +48 -0
- package/dist/esm/transport/node/builders/profile.js +70 -0
- package/dist/esm/transport/node/builders/retry.js +11 -23
- package/dist/esm/transport/node/builders/usync.js +6 -2
- package/dist/esm/transport/node/helpers.js +43 -1
- package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
- package/dist/esm/transport/node/mex/client.js +83 -0
- package/dist/esm/transport/node/mex/persist-ids.js +10 -0
- package/dist/esm/transport/node/usync.js +3 -33
- package/dist/esm/transport/node/xml.js +35 -14
- package/dist/esm/transport/noise/WaClientPayload.js +24 -19
- package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
- package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
- package/dist/esm/transport/noise/WaNoiseSession.js +76 -34
- package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/esm/transport/stream/parse.js +8 -4
- package/dist/esm/util/bytes.js +22 -18
- package/dist/esm/util/index.js +5 -0
- package/dist/esm/util/primitives.js +3 -2
- package/dist/index.js +7 -1
- package/dist/infra/perf/BackgroundQueue.js +482 -0
- package/dist/infra/perf/BoundedTaskQueue.js +3 -1
- package/dist/infra/perf/PromiseDedup.js +24 -0
- package/dist/infra/perf/SharedExclusiveGate.js +113 -0
- package/dist/infra/perf/StoreLock.js +84 -0
- package/dist/media/WaMediaCrypto.js +328 -51
- package/dist/media/WaMediaTransferClient.js +72 -253
- package/dist/media/constants.js +5 -2
- package/dist/media/processor.js +2 -0
- package/dist/message/WaMessageClient.js +26 -19
- package/dist/message/addon-crypto.js +131 -0
- package/dist/message/content.js +211 -14
- package/dist/message/icdc.js +81 -0
- package/dist/message/incoming.js +38 -24
- package/dist/message/phash.js +35 -13
- package/dist/message/reporting-token.js +16 -30
- package/dist/message/use-case-secret.js +1 -1
- package/dist/protocol/abprops.js +163 -0
- package/dist/protocol/appstate.js +10 -41
- package/dist/protocol/browser.js +25 -18
- package/dist/protocol/constants.js +33 -2
- package/dist/protocol/defaults.js +6 -0
- package/dist/protocol/email.js +33 -0
- package/dist/protocol/index.js +8 -5
- package/dist/protocol/jid.js +149 -39
- package/dist/protocol/message.js +62 -2
- package/dist/protocol/nodes.js +8 -2
- package/dist/protocol/notification.js +10 -2
- package/dist/protocol/privacy-token.js +20 -0
- package/dist/protocol/privacy.js +58 -0
- package/dist/protocol/stream.js +27 -2
- package/dist/retry/codec.js +220 -0
- package/dist/retry/constants.js +1 -1
- package/dist/retry/index.js +5 -5
- package/dist/retry/parse.js +51 -30
- package/dist/retry/reason.js +1 -1
- package/dist/retry/replay.js +10 -6
- package/dist/retry/tracker.js +50 -12
- package/dist/signal/api/SignalDeviceSyncApi.js +51 -31
- package/dist/signal/api/SignalDigestSyncApi.js +21 -15
- package/dist/signal/api/SignalIdentitySyncApi.js +29 -14
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
- package/dist/signal/api/SignalRotateKeyApi.js +4 -2
- package/dist/signal/api/SignalSessionSyncApi.js +16 -7
- package/dist/signal/api/result-map.js +13 -0
- package/dist/signal/constants.js +1 -5
- package/dist/signal/crypto/WaAdvSignature.js +2 -44
- package/dist/signal/crypto/constants.js +1 -5
- package/dist/signal/{store/sqlite.js → encoding.js} +41 -25
- package/dist/signal/group/SenderKeyChain.js +2 -2
- package/dist/signal/group/SenderKeyCodec.js +8 -8
- package/dist/signal/group/SenderKeyManager.js +130 -108
- package/dist/signal/index.js +13 -1
- package/dist/signal/registration/keygen.js +7 -4
- package/dist/signal/registration/utils.js +3 -2
- package/dist/signal/session/SignalProtocol.js +158 -81
- package/dist/signal/session/SignalRatchet.js +19 -8
- package/dist/signal/session/SignalSerializer.js +5 -6
- package/dist/signal/session/SignalSession.js +11 -9
- package/dist/signal/session/resolver.js +138 -103
- package/dist/store/contracts/identity.store.js +2 -0
- package/dist/store/contracts/message-secret.store.js +2 -0
- package/dist/store/contracts/pre-key.store.js +2 -0
- package/dist/store/contracts/privacy-token.store.js +2 -0
- package/dist/store/contracts/session.store.js +2 -0
- package/dist/store/createStore.js +142 -192
- package/dist/store/index.js +23 -33
- package/dist/store/locks/appstate.lock.js +29 -0
- package/dist/store/locks/auth.lock.js +18 -0
- package/dist/store/locks/contact.lock.js +23 -0
- package/dist/store/locks/device-list.lock.js +23 -0
- package/dist/store/locks/identity.lock.js +19 -0
- package/dist/store/locks/message-secret.lock.js +20 -0
- package/dist/store/locks/message.lock.js +24 -0
- package/dist/store/locks/participants.lock.js +23 -0
- package/dist/store/locks/pre-key.lock.js +30 -0
- package/dist/store/locks/privacy-token.lock.js +21 -0
- package/dist/store/locks/retry.lock.js +32 -0
- package/dist/store/locks/sender-key.lock.js +55 -0
- package/dist/store/locks/session.lock.js +22 -0
- package/dist/store/locks/signal.lock.js +42 -0
- package/dist/store/locks/thread.lock.js +24 -0
- package/dist/store/noop.store.js +22 -2
- package/dist/store/providers/memory/appstate.store.js +22 -24
- package/dist/store/providers/memory/device-list.store.js +13 -5
- package/dist/store/providers/memory/identity.store.js +35 -0
- package/dist/store/providers/memory/message-secret.store.js +85 -0
- package/dist/store/providers/memory/participants.store.js +3 -0
- package/dist/store/providers/memory/pre-key.store.js +101 -0
- package/dist/store/providers/memory/privacy-token.store.js +47 -0
- package/dist/store/providers/memory/retry.store.js +98 -9
- package/dist/store/providers/memory/sender-key.store.js +6 -1
- package/dist/store/providers/memory/session.store.js +49 -0
- package/dist/store/providers/memory/signal.store.js +1 -147
- package/dist/transport/WaComms.js +7 -4
- package/dist/transport/WaWebSocket.js +9 -7
- package/dist/transport/binary/constants.js +1 -31
- package/dist/transport/binary/decoder.js +4 -4
- package/dist/transport/binary/encoder.js +8 -15
- package/dist/transport/binary/index.js +0 -4
- package/dist/transport/index.js +17 -1
- package/dist/transport/keepalive/WaKeepAlive.js +17 -8
- package/dist/transport/node/WaMobileTcpSocket.js +118 -0
- package/dist/transport/node/WaNodeOrchestrator.js +36 -21
- package/dist/transport/node/builders/abprops.js +23 -0
- package/dist/transport/node/builders/business.js +137 -0
- package/dist/transport/node/builders/device.js +14 -0
- package/dist/transport/node/builders/email.js +72 -0
- package/dist/transport/node/builders/global.js +375 -0
- package/dist/transport/node/builders/message.js +64 -245
- package/dist/transport/node/builders/offline.js +17 -0
- package/dist/transport/node/builders/pairing.js +0 -26
- package/dist/transport/node/builders/prekeys.js +36 -39
- package/dist/transport/node/builders/presence.js +16 -0
- package/dist/transport/node/builders/privacy-token.js +42 -0
- package/dist/transport/node/builders/privacy.js +55 -0
- package/dist/transport/node/builders/profile.js +78 -0
- package/dist/transport/node/builders/retry.js +10 -22
- package/dist/transport/node/builders/usync.js +6 -2
- package/dist/transport/node/helpers.js +46 -1
- package/dist/transport/node/mex/argo-decoder.js +189 -0
- package/dist/transport/node/mex/client.js +86 -0
- package/dist/transport/node/mex/persist-ids.js +13 -0
- package/dist/transport/node/usync.js +2 -32
- package/dist/transport/node/xml.js +35 -14
- package/dist/transport/noise/WaClientPayload.js +26 -21
- package/dist/transport/noise/WaFrameCodec.js +1 -1
- package/dist/transport/noise/WaMobileClientPayload.js +56 -0
- package/dist/transport/noise/WaNoiseCert.js +8 -26
- package/dist/transport/noise/WaNoiseSession.js +75 -33
- package/dist/transport/noise/WaNoiseSocket.js +8 -4
- package/dist/transport/stream/parse.js +7 -3
- package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
- package/dist/types/appstate/encoding.d.ts +7 -0
- package/dist/types/appstate/index.d.ts +3 -3
- package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
- package/dist/types/appstate/types.d.ts +1 -1
- package/dist/types/appstate/utils.d.ts +0 -2
- package/dist/types/auth/WaAuthClient.d.ts +9 -3
- package/dist/types/auth/credentials-flow.d.ts +20 -0
- package/dist/types/auth/index.d.ts +0 -2
- package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
- package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
- package/dist/types/auth/types.d.ts +41 -0
- package/dist/types/client/WaClient.d.ts +44 -18
- package/dist/types/client/WaClientFactory.d.ts +22 -8
- package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
- package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +9 -2
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -2
- package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +16 -1
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +38 -0
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +12 -0
- package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +55 -0
- package/dist/types/client/dirty.d.ts +3 -1
- package/dist/types/client/events/abprops.d.ts +14 -0
- package/dist/types/client/events/devices.d.ts +20 -0
- package/dist/types/client/events/identity.d.ts +9 -0
- package/dist/types/client/events/privacy-token.d.ts +7 -0
- package/dist/types/client/events/registration.d.ts +17 -0
- package/dist/types/client/history-sync.d.ts +9 -6
- package/dist/types/client/incoming.d.ts +9 -2
- package/dist/types/client/index.d.ts +1 -1
- package/dist/types/client/mailbox.d.ts +5 -5
- package/dist/types/client/media.d.ts +31 -0
- package/dist/types/client/messages.d.ts +3 -2
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
- package/dist/types/client/tokens/cs-token.d.ts +10 -0
- package/dist/types/client/tokens/tc-token.d.ts +5 -0
- package/dist/types/client/types.d.ts +151 -4
- package/dist/types/crypto/core/index.d.ts +3 -2
- package/dist/types/crypto/core/nonce.d.ts +2 -0
- package/dist/types/crypto/core/primitives.d.ts +1 -2
- package/dist/types/crypto/core/random.d.ts +2 -1
- package/dist/types/crypto/core/xeddsa.d.ts +2 -0
- package/dist/types/crypto/curves/constants.d.ts +1 -0
- package/dist/types/crypto/index.d.ts +2 -0
- package/dist/types/crypto/math/constants.d.ts +4 -2
- package/dist/types/crypto/math/fe.d.ts +30 -0
- package/dist/types/crypto/math/mod.d.ts +0 -2
- package/dist/types/crypto/math/types.d.ts +11 -4
- package/dist/types/index.d.ts +6 -3
- package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
- package/dist/types/infra/log/PinoLogger.d.ts +1 -1
- package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
- package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
- package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
- package/dist/types/infra/perf/StoreLock.d.ts +11 -0
- package/dist/types/media/WaMediaCrypto.d.ts +16 -6
- package/dist/types/media/WaMediaTransferClient.d.ts +6 -23
- package/dist/types/media/constants.d.ts +3 -1
- package/dist/types/media/index.d.ts +2 -1
- package/dist/types/media/processor.d.ts +28 -0
- package/dist/types/media/types.d.ts +19 -5
- package/dist/types/message/addon-crypto.d.ts +34 -3
- package/dist/types/message/content.d.ts +11 -1
- package/dist/types/message/icdc.d.ts +13 -0
- package/dist/types/message/reporting-token.d.ts +0 -1
- package/dist/types/message/types.d.ts +42 -11
- package/dist/types/protocol/abprops.d.ts +142 -0
- package/dist/types/protocol/appstate.d.ts +0 -11
- package/dist/types/protocol/browser.d.ts +1 -0
- package/dist/types/protocol/constants.d.ts +12 -4
- package/dist/types/protocol/defaults.d.ts +6 -0
- package/dist/types/protocol/email.d.ts +32 -0
- package/dist/types/protocol/index.d.ts +1 -2
- package/dist/types/protocol/jid.d.ts +20 -2
- package/dist/types/protocol/message.d.ts +60 -0
- package/dist/types/protocol/nodes.d.ts +6 -0
- package/dist/types/protocol/notification.d.ts +8 -0
- package/dist/types/protocol/privacy-token.d.ts +17 -0
- package/dist/types/protocol/privacy.d.ts +75 -0
- package/dist/types/protocol/stream.d.ts +31 -0
- package/dist/types/retry/codec.d.ts +3 -0
- package/dist/types/retry/index.d.ts +3 -3
- package/dist/types/retry/parse.d.ts +5 -2
- package/dist/types/retry/reason.d.ts +1 -1
- package/dist/types/retry/tracker.d.ts +1 -0
- package/dist/types/retry/types.d.ts +6 -1
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +9 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +5 -3
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
- package/dist/types/signal/api/result-map.d.ts +1 -0
- package/dist/types/signal/constants.d.ts +0 -3
- package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
- package/dist/types/signal/crypto/constants.d.ts +0 -1
- package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +9 -3
- package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
- package/dist/types/signal/group/SenderKeyManager.d.ts +17 -7
- package/dist/types/signal/index.d.ts +2 -0
- package/dist/types/signal/registration/utils.d.ts +2 -1
- package/dist/types/signal/session/SignalProtocol.d.ts +21 -6
- package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
- package/dist/types/signal/session/resolver.d.ts +11 -4
- package/dist/types/signal/types.d.ts +16 -4
- package/dist/types/store/contracts/appstate.store.d.ts +1 -1
- package/dist/types/store/contracts/identity.store.d.ts +11 -0
- package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
- package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
- package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
- package/dist/types/store/contracts/retry.store.d.ts +7 -0
- package/dist/types/store/contracts/session.store.d.ts +14 -0
- package/dist/types/store/contracts/signal.store.d.ts +1 -27
- package/dist/types/store/createStore.d.ts +1 -1
- package/dist/types/store/index.d.ts +12 -12
- package/dist/types/store/locks/appstate.lock.d.ts +3 -0
- package/dist/types/store/locks/auth.lock.d.ts +3 -0
- package/dist/types/store/locks/contact.lock.d.ts +3 -0
- package/dist/types/store/locks/device-list.lock.d.ts +2 -0
- package/dist/types/store/locks/identity.lock.d.ts +3 -0
- package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
- package/dist/types/store/locks/message.lock.d.ts +3 -0
- package/dist/types/store/locks/participants.lock.d.ts +2 -0
- package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
- package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
- package/dist/types/store/locks/retry.lock.d.ts +2 -0
- package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
- package/dist/types/store/locks/session.lock.d.ts +3 -0
- package/dist/types/store/locks/signal.lock.d.ts +3 -0
- package/dist/types/store/locks/thread.lock.d.ts +3 -0
- package/dist/types/store/noop.store.d.ts +4 -0
- package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
- package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
- package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
- package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
- package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +15 -1
- package/dist/types/store/providers/memory/session.store.d.ts +21 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +2 -43
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
- package/dist/types/store/types.d.ts +69 -61
- package/dist/types/transport/WaWebSocket.d.ts +1 -1
- package/dist/types/transport/binary/constants.d.ts +0 -30
- package/dist/types/transport/binary/index.d.ts +0 -1
- package/dist/types/transport/index.d.ts +8 -1
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
- package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +9 -6
- package/dist/types/transport/node/builders/abprops.d.ts +5 -0
- package/dist/types/transport/node/builders/business.d.ts +29 -0
- package/dist/types/transport/node/builders/device.d.ts +2 -0
- package/dist/types/transport/node/builders/email.d.ts +11 -0
- package/dist/types/transport/node/builders/global.d.ts +102 -0
- package/dist/types/transport/node/builders/message.d.ts +8 -7
- package/dist/types/transport/node/builders/offline.d.ts +2 -0
- package/dist/types/transport/node/builders/pairing.d.ts +0 -2
- package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
- package/dist/types/transport/node/builders/presence.d.ts +6 -0
- package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
- package/dist/types/transport/node/builders/privacy.d.ts +7 -0
- package/dist/types/transport/node/builders/profile.d.ts +8 -0
- package/dist/types/transport/node/builders/retry.d.ts +0 -1
- package/dist/types/transport/node/helpers.d.ts +8 -0
- package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
- package/dist/types/transport/node/mex/client.d.ts +18 -0
- package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
- package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
- package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
- package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
- package/dist/types/transport/types.d.ts +8 -0
- package/dist/types/util/bytes.d.ts +1 -1
- package/dist/types/util/index.d.ts +5 -0
- package/dist/types/util/primitives.d.ts +0 -1
- package/dist/util/bytes.js +22 -18
- package/dist/util/index.js +23 -0
- package/dist/util/primitives.js +2 -2
- package/package.json +34 -10
- package/proto/index.js +1 -1
- package/dist/auth/flow/WaAuthCredentialsFlow.js +0 -130
- package/dist/auth/pairing/constants.js +0 -5
- package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
- package/dist/crypto/core/constants.js +0 -4
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +0 -125
- package/dist/esm/auth/pairing/constants.js +0 -2
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
- package/dist/esm/crypto/core/constants.js +0 -1
- package/dist/esm/retry/outbound.js +0 -82
- package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
- package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
- package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
- package/dist/esm/store/providers/sqlite/connection.js +0 -245
- package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
- package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
- package/dist/esm/store/providers/sqlite/message.store.js +0 -132
- package/dist/esm/store/providers/sqlite/migrations.js +0 -347
- package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
- package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
- package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
- package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
- package/dist/esm/store/providers/sqlite/table-names.js +0 -107
- package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
- package/dist/esm/transport/node/builders/index.js +0 -8
- package/dist/retry/outbound.js +0 -87
- package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
- package/dist/store/providers/sqlite/appstate.store.js +0 -254
- package/dist/store/providers/sqlite/auth.store.js +0 -180
- package/dist/store/providers/sqlite/connection.js +0 -281
- package/dist/store/providers/sqlite/contact.store.js +0 -78
- package/dist/store/providers/sqlite/device-list.store.js +0 -131
- package/dist/store/providers/sqlite/message.store.js +0 -136
- package/dist/store/providers/sqlite/migrations.js +0 -350
- package/dist/store/providers/sqlite/participants.store.js +0 -81
- package/dist/store/providers/sqlite/retry.store.js +0 -145
- package/dist/store/providers/sqlite/sender-key.store.js +0 -202
- package/dist/store/providers/sqlite/signal.store.js +0 -439
- package/dist/store/providers/sqlite/table-names.js +0 -113
- package/dist/store/providers/sqlite/thread.store.js +0 -89
- package/dist/transport/node/builders/index.js +0 -42
- package/dist/types/appstate/store/sqlite.d.ts +0 -7
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
- package/dist/types/auth/pairing/constants.d.ts +0 -2
- package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
- package/dist/types/crypto/core/constants.d.ts +0 -1
- package/dist/types/retry/outbound.d.ts +0 -4
- package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
- package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
- package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
- package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
- package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
- package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
- package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
- package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
- package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
- package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
- package/dist/types/transport/node/builders/index.d.ts +0 -8
- /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function mergePreferredParsedResult(target, key, next, isPreferred) {
|
|
2
|
+
const current = target.get(key);
|
|
3
|
+
if (!current || !isPreferred(current)) {
|
|
4
|
+
target.set(key, next);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export function registerParsedResultByRawAndCanonicalKey(parsedByRawKey, parsedByCanonicalKey, rawKey, canonicalKey, result, isPreferred) {
|
|
8
|
+
mergePreferredParsedResult(parsedByRawKey, rawKey, result, isPreferred);
|
|
9
|
+
mergePreferredParsedResult(parsedByCanonicalKey, canonicalKey, result, isPreferred);
|
|
10
|
+
}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import { SERIALIZED_PUB_KEY_PREFIX as CORE_SERIALIZED_PUB_KEY_PREFIX } from '../crypto/core/constants.js';
|
|
2
1
|
import { TEXT_ENCODER } from '../util/bytes.js';
|
|
3
2
|
export const SIGNAL_VERSION = 3;
|
|
4
3
|
export const SIGNAL_GROUP_VERSION = 3;
|
|
5
|
-
export const SERIALIZED_PUB_KEY_PREFIX = CORE_SERIALIZED_PUB_KEY_PREFIX;
|
|
6
|
-
export const KEY_TYPE_CURVE25519 = 5;
|
|
7
4
|
export const SIGNAL_MAC_SIZE = 8;
|
|
8
|
-
export const SIGNATURE_SIZE = 64;
|
|
9
5
|
export const MAX_PREV_SESSIONS = 40;
|
|
10
6
|
export const MAX_UNUSED_KEYS = 2000;
|
|
11
7
|
export const FUTURE_MESSAGES_MAX = 2000;
|
|
@@ -1,56 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { bytesToBigIntLE, bigIntToBytesLE } from '../../crypto/math/le.js';
|
|
5
|
-
import { modGroup } from '../../crypto/math/mod.js';
|
|
6
|
-
import { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, ADV_PREFIX_HOSTED_DEVICE_SIGNATURE, SIGNAL_PREFIX_SIGNATURE_RANDOM } from '../crypto/constants.js';
|
|
7
|
-
import { assertByteLength, concatBytes } from '../../util/bytes.js';
|
|
1
|
+
import { hmacSign, importHmacKey, toRawPubKey, xeddsaSign, xeddsaVerify } from '../../crypto/index.js';
|
|
2
|
+
import { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, ADV_PREFIX_HOSTED_DEVICE_SIGNATURE } from '../crypto/constants.js';
|
|
3
|
+
import { concatBytes } from '../../util/bytes.js';
|
|
8
4
|
export { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, ADV_PREFIX_HOSTED_DEVICE_SIGNATURE } from '../crypto/constants.js';
|
|
9
|
-
export async function verifySignalSignature(publicKey, message, signature) {
|
|
10
|
-
if (!assertByteLength(signature, 64, 'invalid signal signature length', false)) {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
if ((signature[63] & 0x60) !== 0) {
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
const signalSignature = new Uint8Array(signature);
|
|
17
|
-
const signBit = signalSignature[63] & 0x80;
|
|
18
|
-
signalSignature[63] &= 0x7f;
|
|
19
|
-
const curvePublic = toRawPubKey(publicKey);
|
|
20
|
-
const edPublic = montgomeryToEdwardsPublic(curvePublic, signBit);
|
|
21
|
-
return ed25519VerifyRaw(edPublic, signalSignature, message);
|
|
22
|
-
}
|
|
23
|
-
export async function signSignalMessage(privateKey, message) {
|
|
24
|
-
assertByteLength(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
|
|
25
|
-
const clampedPrivateKey = clampCurvePrivateKeyInPlace(privateKey);
|
|
26
|
-
const privateScalar = bytesToBigIntLE(clampedPrivateKey);
|
|
27
|
-
const encodedPublic = encodeExtendedPoint(scalarMultBase(privateScalar));
|
|
28
|
-
const pubKeySignBit = encodedPublic[31] & 0x80;
|
|
29
|
-
const randomSuffix = await randomBytesAsync(64);
|
|
30
|
-
const hashInput = concatBytes([
|
|
31
|
-
SIGNAL_PREFIX_SIGNATURE_RANDOM,
|
|
32
|
-
clampedPrivateKey,
|
|
33
|
-
message,
|
|
34
|
-
randomSuffix
|
|
35
|
-
]);
|
|
36
|
-
const r = modGroup(bytesToBigIntLE(await sha512(hashInput)));
|
|
37
|
-
const encodedR = encodeExtendedPoint(scalarMultBase(r));
|
|
38
|
-
const hInput = concatBytes([encodedR, encodedPublic, message]);
|
|
39
|
-
const h = modGroup(bytesToBigIntLE(await sha512(hInput)));
|
|
40
|
-
const s = modGroup(r + h * privateScalar);
|
|
41
|
-
const encodedS = bigIntToBytesLE(s, 32);
|
|
42
|
-
encodedS[31] = (encodedS[31] & 0x7f) | pubKeySignBit;
|
|
43
|
-
return concatBytes([encodedR, encodedS]);
|
|
44
|
-
}
|
|
45
5
|
export async function verifyDeviceIdentityAccountSignature(details, accountSignature, identityPublicKey, accountSignatureKey, isHosted = false) {
|
|
46
6
|
const prefix = isHosted ? ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : ADV_PREFIX_ACCOUNT_SIGNATURE;
|
|
47
7
|
const message = concatBytes([prefix, details, identityPublicKey]);
|
|
48
|
-
return
|
|
8
|
+
return xeddsaVerify(toRawPubKey(accountSignatureKey), message, accountSignature);
|
|
49
9
|
}
|
|
50
10
|
export async function generateDeviceSignature(details, identityKeyPair, accountSignatureKey, isHosted = false) {
|
|
51
11
|
const prefix = isHosted ? ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : ADV_PREFIX_DEVICE_SIGNATURE;
|
|
52
12
|
const message = concatBytes([prefix, details, identityKeyPair.pubKey, accountSignatureKey]);
|
|
53
|
-
return
|
|
13
|
+
return xeddsaSign(identityKeyPair.privKey, message);
|
|
54
14
|
}
|
|
55
15
|
export async function computeAdvIdentityHmac(secretKey, details) {
|
|
56
16
|
const key = await importHmacKey(secretKey);
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export const SIGNAL_PREFIX_SIGNATURE_RANDOM = new Uint8Array([
|
|
2
|
-
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
3
|
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
4
|
-
]);
|
|
5
1
|
export const ADV_PREFIX_ACCOUNT_SIGNATURE = new Uint8Array([6, 0]);
|
|
6
2
|
export const ADV_PREFIX_DEVICE_SIGNATURE = new Uint8Array([6, 1]);
|
|
7
3
|
export const ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = new Uint8Array([6, 5]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { proto } from '
|
|
2
|
-
import { WA_DEFAULTS } from '
|
|
3
|
-
import { assertByteLength } from '
|
|
4
|
-
import { asBytes, asNumber, asOptionalBytes, asOptionalNumber, asString, toBoolOrUndef } from '
|
|
1
|
+
import { proto } from '../proto.js';
|
|
2
|
+
import { WA_DEFAULTS } from '../protocol/constants.js';
|
|
3
|
+
import { assertByteLength } from '../util/bytes.js';
|
|
4
|
+
import { asBytes, asNumber, asOptionalBytes, asOptionalNumber, asString, toBoolOrUndef } from '../util/coercion.js';
|
|
5
5
|
export function toSignalAddressParts(address) {
|
|
6
6
|
return {
|
|
7
7
|
user: address.user,
|
|
@@ -46,7 +46,7 @@ export function decodeSignalSignedPreKeyRow(row) {
|
|
|
46
46
|
uploaded: toBoolOrUndef(row.uploaded)
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
function encodeSignalSessionSnapshot(session) {
|
|
49
|
+
export function encodeSignalSessionSnapshot(session) {
|
|
50
50
|
return {
|
|
51
51
|
sessionVersion: 3,
|
|
52
52
|
localRegistrationId: session.local.regId,
|
|
@@ -56,7 +56,7 @@ function encodeSignalSessionSnapshot(session) {
|
|
|
56
56
|
rootKey: session.rootKey,
|
|
57
57
|
previousCounter: session.prevSendChainHighestIndex,
|
|
58
58
|
senderChain: encodeSignalSendChain(session.sendChain),
|
|
59
|
-
receiverChains: session.recvChains
|
|
59
|
+
receiverChains: session.recvChains,
|
|
60
60
|
pendingPreKey: session.initialExchangeInfo
|
|
61
61
|
? {
|
|
62
62
|
preKeyId: session.initialExchangeInfo.remoteOneTimeId ?? undefined,
|
|
@@ -78,22 +78,17 @@ function encodeSignalSendChain(chain) {
|
|
|
78
78
|
messageKeys: []
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
-
function encodeSignalRecvChain(chain) {
|
|
81
|
+
export function encodeSignalRecvChain(chain) {
|
|
82
82
|
return {
|
|
83
83
|
senderRatchetKey: chain.ratchetPubKey,
|
|
84
84
|
chainKey: {
|
|
85
85
|
index: chain.nextMsgIndex,
|
|
86
86
|
key: chain.chainKey
|
|
87
87
|
},
|
|
88
|
-
messageKeys:
|
|
89
|
-
index: messageKey.index,
|
|
90
|
-
cipherKey: messageKey.cipherKey,
|
|
91
|
-
macKey: messageKey.macKey,
|
|
92
|
-
iv: messageKey.iv
|
|
93
|
-
}))
|
|
88
|
+
messageKeys: chain.unusedMsgKeys
|
|
94
89
|
};
|
|
95
90
|
}
|
|
96
|
-
function decodeSignalMessageKey(messageKey, field) {
|
|
91
|
+
export function decodeSignalMessageKey(messageKey, field) {
|
|
97
92
|
const cipherKey = asBytes(messageKey.cipherKey, `${field}.cipherKey`);
|
|
98
93
|
assertByteLength(cipherKey, 32, `invalid ${field}.cipherKey length ${cipherKey.byteLength}`);
|
|
99
94
|
const macKey = asBytes(messageKey.macKey, `${field}.macKey`);
|
|
@@ -107,7 +102,7 @@ function decodeSignalMessageKey(messageKey, field) {
|
|
|
107
102
|
iv
|
|
108
103
|
};
|
|
109
104
|
}
|
|
110
|
-
function decodeSignalRecvChain(chain, field) {
|
|
105
|
+
export function decodeSignalRecvChain(chain, field) {
|
|
111
106
|
const chainKey = chain.chainKey;
|
|
112
107
|
if (!chainKey) {
|
|
113
108
|
throw new Error(`missing ${field}.chainKey`);
|
|
@@ -120,7 +115,7 @@ function decodeSignalRecvChain(chain, field) {
|
|
|
120
115
|
ratchetPubKey,
|
|
121
116
|
nextMsgIndex: asNumber(chainKey.index, `${field}.chainKey.index`),
|
|
122
117
|
chainKey: chainKeyBytes,
|
|
123
|
-
unusedMsgKeys:
|
|
118
|
+
unusedMsgKeys: chain.messageKeys ?? []
|
|
124
119
|
};
|
|
125
120
|
}
|
|
126
121
|
function decodeSignalSendChain(chain, field) {
|
|
@@ -146,7 +141,7 @@ function decodeSignalSendChain(chain, field) {
|
|
|
146
141
|
chainKey: chainKeyBytes
|
|
147
142
|
};
|
|
148
143
|
}
|
|
149
|
-
function decodeSignalSessionSnapshot(session, field) {
|
|
144
|
+
export function decodeSignalSessionSnapshot(session, field) {
|
|
150
145
|
const senderChain = session.senderChain;
|
|
151
146
|
if (!senderChain) {
|
|
152
147
|
throw new Error(`missing ${field}.senderChain`);
|
|
@@ -179,7 +174,7 @@ function decodeSignalSessionSnapshot(session, field) {
|
|
|
179
174
|
},
|
|
180
175
|
rootKey,
|
|
181
176
|
sendChain: decodeSignalSendChain(senderChain, `${field}.senderChain`),
|
|
182
|
-
recvChains:
|
|
177
|
+
recvChains: session.receiverChains ?? [],
|
|
183
178
|
initialExchangeInfo: pendingPreKey
|
|
184
179
|
? {
|
|
185
180
|
remoteOneTimeId: asOptionalNumber(pendingPreKey.preKeyId, `${field}.pendingPreKey.preKeyId`) ??
|
|
@@ -195,7 +190,7 @@ function decodeSignalSessionSnapshot(session, field) {
|
|
|
195
190
|
export function encodeSignalSessionRecord(record) {
|
|
196
191
|
return proto.RecordStructure.encode({
|
|
197
192
|
currentSession: encodeSignalSessionSnapshot(record),
|
|
198
|
-
previousSessions: record.prevSessions
|
|
193
|
+
previousSessions: record.prevSessions
|
|
199
194
|
}).finish();
|
|
200
195
|
}
|
|
201
196
|
export function decodeSignalSessionRecord(raw) {
|
|
@@ -206,7 +201,7 @@ export function decodeSignalSessionRecord(raw) {
|
|
|
206
201
|
const current = decodeSignalSessionSnapshot(decoded.currentSession, 'signal_sessions.currentSession');
|
|
207
202
|
return {
|
|
208
203
|
...current,
|
|
209
|
-
prevSessions:
|
|
204
|
+
prevSessions: decoded.previousSessions ?? []
|
|
210
205
|
};
|
|
211
206
|
}
|
|
212
207
|
export function encodeSenderKeyRecord(record) {
|
|
@@ -222,10 +217,18 @@ export function encodeSenderKeyRecord(record) {
|
|
|
222
217
|
public: record.signingPublicKey,
|
|
223
218
|
private: record.signingPrivateKey
|
|
224
219
|
},
|
|
225
|
-
senderMessageKeys: (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
220
|
+
senderMessageKeys: (() => {
|
|
221
|
+
const src = record.unusedMessageKeys ?? [];
|
|
222
|
+
const arr = new Array(src.length);
|
|
223
|
+
for (let i = 0; i < src.length; i += 1) {
|
|
224
|
+
const messageKey = src[i];
|
|
225
|
+
arr[i] = {
|
|
226
|
+
iteration: messageKey.iteration,
|
|
227
|
+
seed: messageKey.seed
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return arr;
|
|
231
|
+
})()
|
|
229
232
|
}
|
|
230
233
|
]
|
|
231
234
|
}).finish();
|
|
@@ -245,10 +248,18 @@ function decodeSenderKeyState(state, field) {
|
|
|
245
248
|
signingPrivateKey: state.senderSigningKey.private !== null && state.senderSigningKey.private !== undefined
|
|
246
249
|
? asBytes(state.senderSigningKey.private, `${field}.senderSigningKey.private`)
|
|
247
250
|
: undefined,
|
|
248
|
-
unusedMessageKeys: (
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
251
|
+
unusedMessageKeys: (() => {
|
|
252
|
+
const src = state.senderMessageKeys ?? [];
|
|
253
|
+
const arr = new Array(src.length);
|
|
254
|
+
for (let i = 0; i < src.length; i += 1) {
|
|
255
|
+
const messageKey = src[i];
|
|
256
|
+
arr[i] = {
|
|
257
|
+
iteration: asNumber(messageKey.iteration, `${field}.senderMessageKeys[${i}].iteration`),
|
|
258
|
+
seed: asBytes(messageKey.seed, `${field}.senderMessageKeys[${i}].seed`)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return arr;
|
|
262
|
+
})()
|
|
252
263
|
};
|
|
253
264
|
}
|
|
254
265
|
export function decodeSenderKeyRecord(raw, groupId, sender) {
|
|
@@ -281,7 +292,7 @@ export function decodeSenderKeyDistributionRow(row) {
|
|
|
281
292
|
timestampMs: asNumber(row.timestamp_ms, 'sender_key_distribution.timestamp_ms')
|
|
282
293
|
};
|
|
283
294
|
}
|
|
284
|
-
export function
|
|
295
|
+
export function decodeStoreCount(row, field) {
|
|
285
296
|
return row ? asNumber(row.count, field) : 0;
|
|
286
297
|
}
|
|
287
298
|
export function decodeSignalRemoteIdentity(raw) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { hkdf,
|
|
1
|
+
import { hkdf, hmacSign, importHmacKey } from '../../crypto/index.js';
|
|
2
2
|
import { CHAIN_KEY_LABEL, MAX_UNUSED_KEYS, MESSAGE_KEY_LABEL, SENDER_KEY_FUTURE_MESSAGES_MAX, WHISPER_GROUP_INFO } from '../constants.js';
|
|
3
3
|
import { assertByteLength, removeAt } from '../../util/bytes.js';
|
|
4
|
-
export async function selectMessageKey(senderKey, targetIteration) {
|
|
4
|
+
export async function selectMessageKey(senderKey, targetIteration, futureMessagesMax) {
|
|
5
5
|
const delta = targetIteration - senderKey.iteration;
|
|
6
|
-
if (delta > SENDER_KEY_FUTURE_MESSAGES_MAX) {
|
|
6
|
+
if (delta > (futureMessagesMax ?? SENDER_KEY_FUTURE_MESSAGES_MAX)) {
|
|
7
7
|
throw new Error('sender key message is too far in future');
|
|
8
8
|
}
|
|
9
9
|
const currentUnused = senderKey.unusedMessageKeys ?? [];
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readVersionedContent, toSerializedPubKey } from '../../crypto/index.js';
|
|
2
2
|
import { proto } from '../../proto.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
|
|
4
|
+
import { SIGNAL_GROUP_VERSION } from '../constants.js';
|
|
5
|
+
import { assertByteLength } from '../../util/bytes.js';
|
|
5
6
|
export function parseDistributionPayload(payload) {
|
|
6
7
|
const body = readVersionedContent(payload, SIGNAL_GROUP_VERSION, 0);
|
|
7
8
|
const decoded = proto.SenderKeyDistributionMessage.decode(body);
|
|
@@ -15,17 +16,16 @@ export function parseDistributionPayload(payload) {
|
|
|
15
16
|
decoded.signingKey === undefined) {
|
|
16
17
|
throw new Error('invalid sender key distribution message');
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
assertByteLength(chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
|
|
19
|
+
assertByteLength(decoded.chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
|
|
20
20
|
return {
|
|
21
21
|
keyId: decoded.id,
|
|
22
22
|
iteration: decoded.iteration,
|
|
23
|
-
chainKey,
|
|
24
|
-
signingPublicKey: toSerializedPubKey(
|
|
23
|
+
chainKey: decoded.chainKey,
|
|
24
|
+
signingPublicKey: toSerializedPubKey(decoded.signingKey)
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
export function parseSenderKeyMessage(versionContentMac) {
|
|
28
|
-
const body = readVersionedContent(versionContentMac, SIGNAL_GROUP_VERSION,
|
|
28
|
+
const body = readVersionedContent(versionContentMac, SIGNAL_GROUP_VERSION, SIGNAL_SIGNATURE_LENGTH);
|
|
29
29
|
const decoded = proto.SenderKeyMessage.decode(body);
|
|
30
30
|
if (decoded.id === null ||
|
|
31
31
|
decoded.id === undefined ||
|
|
@@ -38,7 +38,7 @@ export function parseSenderKeyMessage(versionContentMac) {
|
|
|
38
38
|
return {
|
|
39
39
|
keyId: decoded.id,
|
|
40
40
|
iteration: decoded.iteration,
|
|
41
|
-
ciphertext:
|
|
41
|
+
ciphertext: decoded.ciphertext,
|
|
42
42
|
versionContentMac
|
|
43
43
|
};
|
|
44
44
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey,
|
|
1
|
+
import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey, prependVersion, randomBytesAsync, randomIntAsync, toRawPubKey, toSerializedPubKey, X25519, xeddsaSign, xeddsaVerify } from '../../crypto/index.js';
|
|
2
|
+
import { StoreLock } from '../../infra/perf/StoreLock.js';
|
|
2
3
|
import { proto } from '../../proto.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { signalAddressKey } from '../../protocol/jid.js';
|
|
5
|
+
import { SIGNAL_SIGNATURE_LENGTH } from '../api/constants.js';
|
|
6
|
+
import { SIGNAL_GROUP_VERSION } from '../constants.js';
|
|
5
7
|
import { deriveSenderKeyMsgKey, selectMessageKey } from '../group/SenderKeyChain.js';
|
|
6
8
|
import { parseDistributionPayload, parseSenderKeyMessage } from '../group/SenderKeyCodec.js';
|
|
7
9
|
import { concatBytes } from '../../util/bytes.js';
|
|
@@ -23,144 +25,161 @@ async function aesCbcDecryptFromSeed(seed, ciphertext) {
|
|
|
23
25
|
return aesCbcDecrypt(await importAesCbcKey(keyBytes), iv, ciphertext);
|
|
24
26
|
}
|
|
25
27
|
export class SenderKeyManager {
|
|
26
|
-
constructor(store) {
|
|
28
|
+
constructor(store, options) {
|
|
29
|
+
this.senderLock = new StoreLock();
|
|
27
30
|
this.store = store;
|
|
31
|
+
this.getFutureMessagesMax = options?.getFutureMessagesMax;
|
|
32
|
+
this.skipSignatureVerification = options?.skipSignatureVerification === true;
|
|
28
33
|
}
|
|
29
|
-
async
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
async prepareGroupEncryption(groupId, sender, plaintext) {
|
|
35
|
+
return this.runWithSenderLock(groupId, sender, async () => {
|
|
36
|
+
const senderKey = await this.ensureSenderKeyInternal(groupId, sender);
|
|
37
|
+
if (!senderKey.signingPrivateKey) {
|
|
38
|
+
throw new Error('sender private signing key is missing');
|
|
39
|
+
}
|
|
40
|
+
const derived = await deriveSenderKeyMsgKey(senderKey.iteration, senderKey.chainKey);
|
|
41
|
+
await this.store.upsertSenderKey({
|
|
42
|
+
...senderKey,
|
|
43
|
+
chainKey: derived.nextChainKey,
|
|
44
|
+
iteration: derived.messageKey.iteration + 1
|
|
45
|
+
});
|
|
46
|
+
const distributionProto = proto.SenderKeyDistributionMessage.encode({
|
|
47
|
+
id: senderKey.keyId,
|
|
48
|
+
iteration: senderKey.iteration,
|
|
49
|
+
chainKey: senderKey.chainKey,
|
|
50
|
+
signingKey: senderKey.signingPublicKey
|
|
51
|
+
}).finish();
|
|
52
|
+
const distributionMessage = {
|
|
53
|
+
groupId,
|
|
54
|
+
axolotlSenderKeyDistributionMessage: prependVersion(distributionProto, SIGNAL_GROUP_VERSION)
|
|
55
|
+
};
|
|
56
|
+
const messagePayload = await aesCbcEncryptFromSeed(derived.messageKey.seed, plaintext);
|
|
57
|
+
const senderKeyMessage = proto.SenderKeyMessage.encode({
|
|
58
|
+
id: senderKey.keyId,
|
|
59
|
+
iteration: derived.messageKey.iteration,
|
|
60
|
+
ciphertext: messagePayload
|
|
61
|
+
}).finish();
|
|
62
|
+
const versionedContent = prependVersion(senderKeyMessage, SIGNAL_GROUP_VERSION);
|
|
63
|
+
const signature = await xeddsaSign(senderKey.signingPrivateKey, versionedContent);
|
|
64
|
+
if (signature.length !== SIGNAL_SIGNATURE_LENGTH) {
|
|
65
|
+
throw new Error(`invalid sender key signature length ${signature.length}`);
|
|
66
|
+
}
|
|
67
|
+
const ciphertext = {
|
|
68
|
+
groupId,
|
|
69
|
+
sender,
|
|
70
|
+
keyId: senderKey.keyId,
|
|
71
|
+
iteration: derived.messageKey.iteration,
|
|
72
|
+
ciphertext: concatBytes([versionedContent, signature])
|
|
73
|
+
};
|
|
74
|
+
await this.store.upsertSenderKeyDistribution({
|
|
75
|
+
groupId,
|
|
76
|
+
sender,
|
|
77
|
+
keyId: senderKey.keyId,
|
|
78
|
+
timestampMs: Date.now()
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
distributionMessage,
|
|
82
|
+
ciphertext,
|
|
83
|
+
keyId: senderKey.keyId
|
|
84
|
+
};
|
|
43
85
|
});
|
|
44
|
-
return {
|
|
45
|
-
groupId,
|
|
46
|
-
axolotlSenderKeyDistributionMessage: payload
|
|
47
|
-
};
|
|
48
86
|
}
|
|
49
|
-
async filterParticipantsNeedingDistribution(groupId,
|
|
87
|
+
async filterParticipantsNeedingDistribution(groupId, senderKeyId, participants) {
|
|
50
88
|
if (participants.length === 0) {
|
|
51
89
|
return [];
|
|
52
90
|
}
|
|
53
|
-
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
54
91
|
const distributed = await this.store.getDeviceSenderKeyDistributions(groupId, participants);
|
|
55
|
-
|
|
92
|
+
const pendingParticipants = new Array(participants.length);
|
|
93
|
+
let pendingCount = 0;
|
|
94
|
+
for (let index = 0; index < participants.length; index += 1) {
|
|
56
95
|
const record = distributed[index];
|
|
57
|
-
|
|
58
|
-
|
|
96
|
+
if (!record || record.keyId !== senderKeyId) {
|
|
97
|
+
pendingParticipants[pendingCount] = participants[index];
|
|
98
|
+
pendingCount += 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
pendingParticipants.length = pendingCount;
|
|
102
|
+
return pendingParticipants;
|
|
59
103
|
}
|
|
60
|
-
async markSenderKeyDistributed(groupId,
|
|
104
|
+
async markSenderKeyDistributed(groupId, senderKeyId, participants) {
|
|
61
105
|
if (participants.length === 0) {
|
|
62
106
|
return;
|
|
63
107
|
}
|
|
64
|
-
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
65
108
|
const timestampMs = Date.now();
|
|
66
109
|
const distributions = new Array(participants.length);
|
|
67
110
|
for (let index = 0; index < participants.length; index += 1) {
|
|
68
111
|
distributions[index] = {
|
|
69
112
|
groupId,
|
|
70
113
|
sender: participants[index],
|
|
71
|
-
keyId:
|
|
114
|
+
keyId: senderKeyId,
|
|
72
115
|
timestampMs
|
|
73
116
|
};
|
|
74
117
|
}
|
|
75
118
|
await this.store.upsertSenderKeyDistributions(distributions);
|
|
76
119
|
}
|
|
77
120
|
async processSenderKeyDistributionPayload(groupId, sender, payload) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
sender,
|
|
85
|
-
keyId: parsed.keyId,
|
|
86
|
-
iteration: parsed.iteration,
|
|
87
|
-
chainKey: parsed.chainKey,
|
|
88
|
-
signingPublicKey: parsed.signingPublicKey,
|
|
89
|
-
unusedMessageKeys: []
|
|
90
|
-
};
|
|
91
|
-
await Promise.all([
|
|
92
|
-
this.store.upsertSenderKey(record),
|
|
93
|
-
this.store.upsertSenderKeyDistribution({
|
|
121
|
+
return this.runWithSenderLock(groupId, sender, async () => {
|
|
122
|
+
if (groupId.length === 0) {
|
|
123
|
+
throw new Error('sender key distribution missing groupId');
|
|
124
|
+
}
|
|
125
|
+
const parsed = parseDistributionPayload(payload);
|
|
126
|
+
const record = {
|
|
94
127
|
groupId,
|
|
95
128
|
sender,
|
|
96
129
|
keyId: parsed.keyId,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
ciphertext: messagePayload
|
|
113
|
-
}).finish();
|
|
114
|
-
const versionedContent = prependVersion(senderKeyMessage, SIGNAL_GROUP_VERSION);
|
|
115
|
-
const signature = await signSignalMessage(senderKey.signingPrivateKey, versionedContent);
|
|
116
|
-
if (signature.length !== SIGNATURE_SIZE) {
|
|
117
|
-
throw new Error(`invalid sender key signature length ${signature.length}`);
|
|
118
|
-
}
|
|
119
|
-
const ciphertext = concatBytes([versionedContent, signature]);
|
|
120
|
-
await this.store.upsertSenderKey({
|
|
121
|
-
...senderKey,
|
|
122
|
-
chainKey: derived.nextChainKey,
|
|
123
|
-
iteration: derived.messageKey.iteration + 1
|
|
130
|
+
iteration: parsed.iteration,
|
|
131
|
+
chainKey: parsed.chainKey,
|
|
132
|
+
signingPublicKey: parsed.signingPublicKey,
|
|
133
|
+
unusedMessageKeys: []
|
|
134
|
+
};
|
|
135
|
+
await Promise.all([
|
|
136
|
+
this.store.upsertSenderKey(record),
|
|
137
|
+
this.store.upsertSenderKeyDistribution({
|
|
138
|
+
groupId,
|
|
139
|
+
sender,
|
|
140
|
+
keyId: parsed.keyId,
|
|
141
|
+
timestampMs: Date.now()
|
|
142
|
+
})
|
|
143
|
+
]);
|
|
144
|
+
return record;
|
|
124
145
|
});
|
|
125
|
-
return {
|
|
126
|
-
groupId,
|
|
127
|
-
sender,
|
|
128
|
-
keyId: senderKey.keyId,
|
|
129
|
-
iteration: derived.messageKey.iteration,
|
|
130
|
-
ciphertext
|
|
131
|
-
};
|
|
132
146
|
}
|
|
133
147
|
async decryptGroupMessage(payload) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
payload.keyId !==
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
payload.iteration !==
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
148
|
+
return this.runWithSenderLock(payload.groupId, payload.sender, async () => {
|
|
149
|
+
const parsed = parseSenderKeyMessage(payload.ciphertext);
|
|
150
|
+
const senderKey = await this.store.getDeviceSenderKey(payload.groupId, payload.sender);
|
|
151
|
+
if (!senderKey) {
|
|
152
|
+
throw new Error('missing sender key');
|
|
153
|
+
}
|
|
154
|
+
if (senderKey.keyId !== parsed.keyId) {
|
|
155
|
+
throw new Error('sender key id mismatch');
|
|
156
|
+
}
|
|
157
|
+
if (payload.keyId !== undefined &&
|
|
158
|
+
payload.keyId !== null &&
|
|
159
|
+
parsed.keyId !== payload.keyId) {
|
|
160
|
+
throw new Error('sender key id mismatch');
|
|
161
|
+
}
|
|
162
|
+
if (payload.iteration !== undefined &&
|
|
163
|
+
payload.iteration !== null &&
|
|
164
|
+
parsed.iteration !== payload.iteration) {
|
|
165
|
+
throw new Error('sender key iteration mismatch');
|
|
166
|
+
}
|
|
167
|
+
if (!this.skipSignatureVerification) {
|
|
168
|
+
const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
|
|
169
|
+
const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - SIGNAL_SIGNATURE_LENGTH);
|
|
170
|
+
const validSignature = await xeddsaVerify(toRawPubKey(senderKey.signingPublicKey), signedContent, signature);
|
|
171
|
+
if (!validSignature) {
|
|
172
|
+
throw new Error('invalid sender key signature');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const selected = await selectMessageKey(senderKey, parsed.iteration, this.getFutureMessagesMax?.());
|
|
176
|
+
// Keep decrypt + persist ordered: failed decrypt must not advance sender-key state.
|
|
177
|
+
const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
|
|
178
|
+
await this.store.upsertSenderKey(selected.updatedRecord);
|
|
179
|
+
return plaintext;
|
|
180
|
+
});
|
|
162
181
|
}
|
|
163
|
-
async
|
|
182
|
+
async ensureSenderKeyInternal(groupId, sender) {
|
|
164
183
|
const existing = await this.store.getDeviceSenderKey(groupId, sender);
|
|
165
184
|
if (existing) {
|
|
166
185
|
return existing;
|
|
@@ -183,4 +202,7 @@ export class SenderKeyManager {
|
|
|
183
202
|
await this.store.upsertSenderKey(created);
|
|
184
203
|
return created;
|
|
185
204
|
}
|
|
205
|
+
runWithSenderLock(groupId, sender, task) {
|
|
206
|
+
return this.senderLock.run(`senderKey:${groupId}:${signalAddressKey(sender)}`, task);
|
|
207
|
+
}
|
|
186
208
|
}
|
package/dist/esm/signal/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { decodeSignalPreKeyRow, decodeSignalRegistrationRow, decodeSignalRemoteIdentity, decodeSignalSessionRecord, decodeSignalSignedPreKeyRow, decodeSenderKeyDistributionRow, decodeSenderKeyRecord, decodeStoreCount, encodeSenderKeyRecord, encodeSignalSessionRecord, toSignalAddressParts } from './encoding.js';
|
|
1
2
|
export { generatePreKeyPair, generateRegistrationId, generateRegistrationInfo, generateSignedPreKey } from './registration/keygen.js';
|
|
2
3
|
export { buildPreKeyUploadIq, parsePreKeyUploadFailure } from './api/prekeys.js';
|
|
3
4
|
export { SignalDigestSyncApi } from './api/SignalDigestSyncApi.js';
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { randomIntAsync } from '../../crypto/index.js';
|
|
1
|
+
import { randomIntAsync, xeddsaSign } from '../../crypto/index.js';
|
|
2
2
|
import { toSerializedPubKey } from '../../crypto/core/keys.js';
|
|
3
3
|
import { X25519 } from '../../crypto/curves/X25519.js';
|
|
4
|
-
import { signSignalMessage } from '../crypto/WaAdvSignature.js';
|
|
5
4
|
export async function generateRegistrationInfo() {
|
|
5
|
+
const [registrationId, identityKeyPair] = await Promise.all([
|
|
6
|
+
generateRegistrationId(),
|
|
7
|
+
X25519.generateKeyPair()
|
|
8
|
+
]);
|
|
6
9
|
return {
|
|
7
|
-
registrationId
|
|
8
|
-
identityKeyPair
|
|
10
|
+
registrationId,
|
|
11
|
+
identityKeyPair
|
|
9
12
|
};
|
|
10
13
|
}
|
|
11
14
|
export async function generatePreKeyPair(keyId) {
|
|
@@ -18,7 +21,7 @@ export async function generatePreKeyPair(keyId) {
|
|
|
18
21
|
export async function generateSignedPreKey(keyId, signingPrivateKey) {
|
|
19
22
|
const keyPair = await X25519.generateKeyPair();
|
|
20
23
|
const serializedPubKey = toSerializedPubKey(keyPair.pubKey);
|
|
21
|
-
const signature = await
|
|
24
|
+
const signature = await xeddsaSign(signingPrivateKey, serializedPubKey);
|
|
22
25
|
return {
|
|
23
26
|
keyId,
|
|
24
27
|
keyPair,
|