zapo-js 0.1.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 +235 -0
- package/dist/appstate/WaAppStateCrypto.js +202 -0
- package/dist/appstate/WaAppStateSyncClient.js +808 -0
- package/dist/appstate/WaAppStateSyncResponseParser.js +71 -0
- package/dist/appstate/constants.js +23 -0
- package/dist/appstate/index.js +28 -0
- package/dist/appstate/store/sqlite.js +55 -0
- package/dist/appstate/types.js +2 -0
- package/dist/appstate/utils.js +84 -0
- package/dist/auth/WaAuthClient.js +266 -0
- package/dist/auth/flow/WaAuthCredentialsFlow.js +123 -0
- package/dist/auth/index.js +27 -0
- package/dist/auth/pairing/WaPairingCodeCrypto.js +75 -0
- package/dist/auth/pairing/WaPairingFlow.js +328 -0
- package/dist/auth/pairing/WaQrFlow.js +86 -0
- package/dist/auth/pairing/constants.js +5 -0
- package/dist/auth/types.js +2 -0
- package/dist/client/WaClient.js +749 -0
- package/dist/client/WaClientFactory.js +381 -0
- package/dist/client/coordinators/WaGroupCoordinator.js +191 -0
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +315 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +1061 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +200 -0
- package/dist/client/coordinators/WaRetryCoordinator.js +494 -0
- package/dist/client/coordinators/WaStreamControlCoordinator.js +123 -0
- package/dist/client/dirty.js +254 -0
- package/dist/client/events/chat.js +226 -0
- package/dist/client/events/group.js +410 -0
- package/dist/client/history-sync.js +122 -0
- package/dist/client/incoming.js +236 -0
- package/dist/client/index.js +5 -0
- package/dist/client/mailbox.js +49 -0
- package/dist/client/messages.js +152 -0
- package/dist/client/types.js +2 -0
- package/dist/crypto/core/constants.js +4 -0
- package/dist/crypto/core/encoding.js +29 -0
- package/dist/crypto/core/hkdf.js +26 -0
- package/dist/crypto/core/index.js +43 -0
- package/dist/crypto/core/keys.js +73 -0
- package/dist/crypto/core/nonce.js +18 -0
- package/dist/crypto/core/primitives.js +121 -0
- package/dist/crypto/core/random.js +32 -0
- package/dist/crypto/curves/Ed25519.js +42 -0
- package/dist/crypto/curves/X25519.js +64 -0
- package/dist/crypto/curves/constants.js +6 -0
- package/dist/crypto/curves/types.js +9 -0
- package/dist/crypto/index.js +22 -0
- package/dist/crypto/math/constants.js +44 -0
- package/dist/crypto/math/edwards.js +64 -0
- package/dist/crypto/math/le.js +20 -0
- package/dist/crypto/math/mod.js +38 -0
- package/dist/crypto/math/types.js +2 -0
- package/dist/esm/appstate/WaAppStateCrypto.js +198 -0
- package/dist/esm/appstate/WaAppStateSyncClient.js +803 -0
- package/dist/esm/appstate/WaAppStateSyncResponseParser.js +67 -0
- package/dist/esm/appstate/constants.js +20 -0
- package/dist/esm/appstate/index.js +6 -0
- package/dist/esm/appstate/store/sqlite.js +49 -0
- package/dist/esm/appstate/types.js +1 -0
- package/dist/esm/appstate/utils.js +75 -0
- package/dist/esm/auth/WaAuthClient.js +262 -0
- package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +118 -0
- package/dist/esm/auth/index.js +5 -0
- package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +71 -0
- package/dist/esm/auth/pairing/WaPairingFlow.js +324 -0
- package/dist/esm/auth/pairing/WaQrFlow.js +82 -0
- package/dist/esm/auth/pairing/constants.js +2 -0
- package/dist/esm/auth/types.js +1 -0
- package/dist/esm/client/WaClient.js +745 -0
- package/dist/esm/client/WaClientFactory.js +377 -0
- package/dist/esm/client/coordinators/WaGroupCoordinator.js +188 -0
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +311 -0
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +1057 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +196 -0
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +490 -0
- package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +120 -0
- package/dist/esm/client/dirty.js +250 -0
- package/dist/esm/client/events/chat.js +223 -0
- package/dist/esm/client/events/group.js +407 -0
- package/dist/esm/client/history-sync.js +119 -0
- package/dist/esm/client/incoming.js +227 -0
- package/dist/esm/client/index.js +1 -0
- package/dist/esm/client/mailbox.js +46 -0
- package/dist/esm/client/messages.js +148 -0
- package/dist/esm/client/types.js +1 -0
- package/dist/esm/crypto/core/constants.js +1 -0
- package/dist/esm/crypto/core/encoding.js +25 -0
- package/dist/esm/crypto/core/hkdf.js +22 -0
- package/dist/esm/crypto/core/index.js +11 -0
- package/dist/esm/crypto/core/keys.js +66 -0
- package/dist/esm/crypto/core/nonce.js +15 -0
- package/dist/esm/crypto/core/primitives.js +102 -0
- package/dist/esm/crypto/core/random.js +28 -0
- package/dist/esm/crypto/curves/Ed25519.js +38 -0
- package/dist/esm/crypto/curves/X25519.js +58 -0
- package/dist/esm/crypto/curves/constants.js +3 -0
- package/dist/esm/crypto/curves/types.js +6 -0
- package/dist/esm/crypto/index.js +3 -0
- package/dist/esm/crypto/math/constants.js +41 -0
- package/dist/esm/crypto/math/edwards.js +60 -0
- package/dist/esm/crypto/math/le.js +16 -0
- package/dist/esm/crypto/math/mod.js +31 -0
- package/dist/esm/crypto/math/types.js +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/infra/log/ConsoleLogger.js +40 -0
- package/dist/esm/infra/log/PinoLogger.js +73 -0
- package/dist/esm/infra/log/types.js +1 -0
- package/dist/esm/infra/perf/BoundedTaskQueue.js +62 -0
- package/dist/esm/media/WaMediaCrypto.js +224 -0
- package/dist/esm/media/WaMediaTransferClient.js +361 -0
- package/dist/esm/media/conn.js +33 -0
- package/dist/esm/media/constants.js +18 -0
- package/dist/esm/media/index.js +3 -0
- package/dist/esm/media/types.js +1 -0
- package/dist/esm/message/WaMessageClient.js +210 -0
- package/dist/esm/message/ack.js +46 -0
- package/dist/esm/message/content.js +20 -0
- package/dist/esm/message/device-sent.js +49 -0
- package/dist/esm/message/incoming.js +318 -0
- package/dist/esm/message/index.js +2 -0
- package/dist/esm/message/padding.js +20 -0
- package/dist/esm/message/phash.js +25 -0
- package/dist/esm/message/types.js +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/proto.js +3 -0
- package/dist/esm/protocol/appstate.js +34 -0
- package/dist/esm/protocol/auth.js +12 -0
- package/dist/esm/protocol/browser.js +41 -0
- package/dist/esm/protocol/constants.js +11 -0
- package/dist/esm/protocol/defaults.js +27 -0
- package/dist/esm/protocol/dirty.js +26 -0
- package/dist/esm/protocol/group.js +5 -0
- package/dist/esm/protocol/index.js +11 -0
- package/dist/esm/protocol/jid.js +94 -0
- package/dist/esm/protocol/media.js +20 -0
- package/dist/esm/protocol/message.js +16 -0
- package/dist/esm/protocol/nodes.js +83 -0
- package/dist/esm/protocol/notification.js +50 -0
- package/dist/esm/protocol/stream.js +60 -0
- package/dist/esm/retry/constants.js +20 -0
- package/dist/esm/retry/index.js +5 -0
- package/dist/esm/retry/outbound.js +83 -0
- package/dist/esm/retry/parse.js +130 -0
- package/dist/esm/retry/reason.js +50 -0
- package/dist/esm/retry/replay.js +177 -0
- package/dist/esm/retry/types.js +1 -0
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +185 -0
- package/dist/esm/signal/api/SignalDigestSyncApi.js +179 -0
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +111 -0
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +141 -0
- package/dist/esm/signal/api/SignalRotateKeyApi.js +59 -0
- package/dist/esm/signal/api/SignalSessionSyncApi.js +187 -0
- package/dist/esm/signal/api/codec.js +23 -0
- package/dist/esm/signal/api/constants.js +9 -0
- package/dist/esm/signal/api/prekeys.js +9 -0
- package/dist/esm/signal/constants.js +16 -0
- package/dist/esm/signal/crypto/WaAdvSignature.js +60 -0
- package/dist/esm/signal/crypto/constants.js +8 -0
- package/dist/esm/signal/group/SenderKeyChain.js +97 -0
- package/dist/esm/signal/group/SenderKeyCodec.js +46 -0
- package/dist/esm/signal/group/SenderKeyManager.js +176 -0
- package/dist/esm/signal/index.js +11 -0
- package/dist/esm/signal/registration/keygen.js +31 -0
- package/dist/esm/signal/registration/utils.js +16 -0
- package/dist/esm/signal/session/SignalProtocol.js +122 -0
- package/dist/esm/signal/session/SignalRatchet.js +260 -0
- package/dist/esm/signal/session/SignalSerializer.js +63 -0
- package/dist/esm/signal/session/SignalSession.js +153 -0
- package/dist/esm/signal/store/sqlite.js +310 -0
- package/dist/esm/signal/types.js +1 -0
- package/dist/esm/store/contracts/appstate.store.js +1 -0
- package/dist/esm/store/contracts/auth.store.js +1 -0
- package/dist/esm/store/contracts/contact.store.js +1 -0
- package/dist/esm/store/contracts/device-list.store.js +1 -0
- package/dist/esm/store/contracts/message.store.js +1 -0
- package/dist/esm/store/contracts/participants.store.js +1 -0
- package/dist/esm/store/contracts/retry.store.js +1 -0
- package/dist/esm/store/contracts/sender-key.store.js +1 -0
- package/dist/esm/store/contracts/signal.store.js +1 -0
- package/dist/esm/store/contracts/thread.store.js +1 -0
- package/dist/esm/store/createStore.js +278 -0
- package/dist/esm/store/index.js +20 -0
- package/dist/esm/store/noop.store.js +43 -0
- package/dist/esm/store/providers/memory/appstate.store.js +101 -0
- package/dist/esm/store/providers/memory/contact.store.js +23 -0
- package/dist/esm/store/providers/memory/device-list.store.js +86 -0
- package/dist/esm/store/providers/memory/message.store.js +40 -0
- package/dist/esm/store/providers/memory/participants.store.js +61 -0
- package/dist/esm/store/providers/memory/retry.store.js +71 -0
- package/dist/esm/store/providers/memory/sender-key.store.js +88 -0
- package/dist/esm/store/providers/memory/signal.store.js +170 -0
- package/dist/esm/store/providers/memory/thread.store.js +34 -0
- package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +37 -0
- package/dist/esm/store/providers/sqlite/appstate.store.js +169 -0
- package/dist/esm/store/providers/sqlite/auth.store.js +176 -0
- package/dist/esm/store/providers/sqlite/connection.js +240 -0
- package/dist/esm/store/providers/sqlite/contact.store.js +61 -0
- package/dist/esm/store/providers/sqlite/device-list.store.js +155 -0
- package/dist/esm/store/providers/sqlite/message.store.js +119 -0
- package/dist/esm/store/providers/sqlite/migrations.js +347 -0
- package/dist/esm/store/providers/sqlite/participants.store.js +85 -0
- package/dist/esm/store/providers/sqlite/retry.store.js +144 -0
- package/dist/esm/store/providers/sqlite/sender-key.store.js +203 -0
- package/dist/esm/store/providers/sqlite/signal.store.js +353 -0
- package/dist/esm/store/providers/sqlite/thread.store.js +72 -0
- package/dist/esm/store/types.js +1 -0
- package/dist/esm/transport/WaComms.js +527 -0
- package/dist/esm/transport/WaWebSocket.js +361 -0
- package/dist/esm/transport/binary/constants.js +96 -0
- package/dist/esm/transport/binary/decoder.js +275 -0
- package/dist/esm/transport/binary/encoder.js +210 -0
- package/dist/esm/transport/binary/index.js +4 -0
- package/dist/esm/transport/binary/tokens.js +1280 -0
- package/dist/esm/transport/index.js +6 -0
- package/dist/esm/transport/keepalive/WaKeepAlive.js +141 -0
- package/dist/esm/transport/node/WaNodeOrchestrator.js +143 -0
- package/dist/esm/transport/node/WaNodeTransport.js +64 -0
- package/dist/esm/transport/node/builders/accountSync.js +101 -0
- package/dist/esm/transport/node/builders/group.js +47 -0
- package/dist/esm/transport/node/builders/index.js +7 -0
- package/dist/esm/transport/node/builders/media.js +10 -0
- package/dist/esm/transport/node/builders/message.js +317 -0
- package/dist/esm/transport/node/builders/pairing.js +130 -0
- package/dist/esm/transport/node/builders/prekeys.js +102 -0
- package/dist/esm/transport/node/builders/retry.js +116 -0
- package/dist/esm/transport/node/helpers.js +37 -0
- package/dist/esm/transport/node/query.js +53 -0
- package/dist/esm/transport/node/xml.js +39 -0
- package/dist/esm/transport/noise/WaClientPayload.js +162 -0
- package/dist/esm/transport/noise/WaFrameCodec.js +121 -0
- package/dist/esm/transport/noise/WaNoiseCert.js +74 -0
- package/dist/esm/transport/noise/WaNoiseHandshake.js +57 -0
- package/dist/esm/transport/noise/WaNoiseSession.js +322 -0
- package/dist/esm/transport/noise/WaNoiseSocket.js +17 -0
- package/dist/esm/transport/noise/constants.js +8 -0
- package/dist/esm/transport/noise/types.js +1 -0
- package/dist/esm/transport/stream/parse.js +91 -0
- package/dist/esm/transport/types.js +1 -0
- package/dist/esm/util/async.js +5 -0
- package/dist/esm/util/base64.js +18 -0
- package/dist/esm/util/bytes.js +275 -0
- package/dist/esm/util/coercion.js +56 -0
- package/dist/esm/util/collections.js +27 -0
- package/dist/esm/util/primitives.js +32 -0
- package/dist/esm/util/runtime.js +15 -0
- package/dist/esm/util/signal-address.js +5 -0
- package/dist/index.js +52 -0
- package/dist/infra/log/ConsoleLogger.js +44 -0
- package/dist/infra/log/PinoLogger.js +111 -0
- package/dist/infra/log/types.js +2 -0
- package/dist/infra/perf/BoundedTaskQueue.js +67 -0
- package/dist/media/WaMediaCrypto.js +228 -0
- package/dist/media/WaMediaTransferClient.js +365 -0
- package/dist/media/conn.js +36 -0
- package/dist/media/constants.js +21 -0
- package/dist/media/index.js +9 -0
- package/dist/media/types.js +2 -0
- package/dist/message/WaMessageClient.js +214 -0
- package/dist/message/ack.js +52 -0
- package/dist/message/content.js +24 -0
- package/dist/message/device-sent.js +53 -0
- package/dist/message/incoming.js +321 -0
- package/dist/message/index.js +20 -0
- package/dist/message/padding.js +24 -0
- package/dist/message/phash.js +28 -0
- package/dist/message/types.js +2 -0
- package/dist/proto.js +5 -0
- package/dist/protocol/appstate.js +37 -0
- package/dist/protocol/auth.js +15 -0
- package/dist/protocol/browser.js +45 -0
- package/dist/protocol/constants.js +46 -0
- package/dist/protocol/defaults.js +30 -0
- package/dist/protocol/dirty.js +29 -0
- package/dist/protocol/group.js +8 -0
- package/dist/protocol/index.js +53 -0
- package/dist/protocol/jid.js +107 -0
- package/dist/protocol/media.js +24 -0
- package/dist/protocol/message.js +19 -0
- package/dist/protocol/nodes.js +86 -0
- package/dist/protocol/notification.js +53 -0
- package/dist/protocol/stream.js +63 -0
- package/dist/retry/constants.js +23 -0
- package/dist/retry/index.js +19 -0
- package/dist/retry/outbound.js +88 -0
- package/dist/retry/parse.js +133 -0
- package/dist/retry/reason.js +53 -0
- package/dist/retry/replay.js +181 -0
- package/dist/retry/types.js +2 -0
- package/dist/signal/api/SignalDeviceSyncApi.js +189 -0
- package/dist/signal/api/SignalDigestSyncApi.js +183 -0
- package/dist/signal/api/SignalIdentitySyncApi.js +115 -0
- package/dist/signal/api/SignalMissingPreKeysSyncApi.js +145 -0
- package/dist/signal/api/SignalRotateKeyApi.js +63 -0
- package/dist/signal/api/SignalSessionSyncApi.js +191 -0
- package/dist/signal/api/codec.js +27 -0
- package/dist/signal/api/constants.js +12 -0
- package/dist/signal/api/prekeys.js +16 -0
- package/dist/signal/constants.js +19 -0
- package/dist/signal/crypto/WaAdvSignature.js +72 -0
- package/dist/signal/crypto/constants.js +11 -0
- package/dist/signal/group/SenderKeyChain.js +101 -0
- package/dist/signal/group/SenderKeyCodec.js +50 -0
- package/dist/signal/group/SenderKeyManager.js +180 -0
- package/dist/signal/index.js +29 -0
- package/dist/signal/registration/keygen.js +37 -0
- package/dist/signal/registration/utils.js +19 -0
- package/dist/signal/session/SignalProtocol.js +126 -0
- package/dist/signal/session/SignalRatchet.js +268 -0
- package/dist/signal/session/SignalSerializer.js +69 -0
- package/dist/signal/session/SignalSession.js +165 -0
- package/dist/signal/store/sqlite.js +324 -0
- package/dist/signal/types.js +2 -0
- package/dist/store/contracts/appstate.store.js +2 -0
- package/dist/store/contracts/auth.store.js +2 -0
- package/dist/store/contracts/contact.store.js +2 -0
- package/dist/store/contracts/device-list.store.js +2 -0
- package/dist/store/contracts/message.store.js +2 -0
- package/dist/store/contracts/participants.store.js +2 -0
- package/dist/store/contracts/retry.store.js +2 -0
- package/dist/store/contracts/sender-key.store.js +2 -0
- package/dist/store/contracts/signal.store.js +2 -0
- package/dist/store/contracts/thread.store.js +2 -0
- package/dist/store/createStore.js +281 -0
- package/dist/store/index.js +43 -0
- package/dist/store/noop.store.js +46 -0
- package/dist/store/providers/memory/appstate.store.js +105 -0
- package/dist/store/providers/memory/contact.store.js +27 -0
- package/dist/store/providers/memory/device-list.store.js +90 -0
- package/dist/store/providers/memory/message.store.js +44 -0
- package/dist/store/providers/memory/participants.store.js +65 -0
- package/dist/store/providers/memory/retry.store.js +75 -0
- package/dist/store/providers/memory/sender-key.store.js +92 -0
- package/dist/store/providers/memory/signal.store.js +174 -0
- package/dist/store/providers/memory/thread.store.js +38 -0
- package/dist/store/providers/sqlite/BaseSqliteStore.js +41 -0
- package/dist/store/providers/sqlite/appstate.store.js +173 -0
- package/dist/store/providers/sqlite/auth.store.js +180 -0
- package/dist/store/providers/sqlite/connection.js +276 -0
- package/dist/store/providers/sqlite/contact.store.js +65 -0
- package/dist/store/providers/sqlite/device-list.store.js +159 -0
- package/dist/store/providers/sqlite/message.store.js +123 -0
- package/dist/store/providers/sqlite/migrations.js +350 -0
- package/dist/store/providers/sqlite/participants.store.js +89 -0
- package/dist/store/providers/sqlite/retry.store.js +148 -0
- package/dist/store/providers/sqlite/sender-key.store.js +207 -0
- package/dist/store/providers/sqlite/signal.store.js +357 -0
- package/dist/store/providers/sqlite/thread.store.js +76 -0
- package/dist/store/types.js +2 -0
- package/dist/transport/WaComms.js +531 -0
- package/dist/transport/WaWebSocket.js +365 -0
- package/dist/transport/binary/constants.js +99 -0
- package/dist/transport/binary/decoder.js +279 -0
- package/dist/transport/binary/encoder.js +214 -0
- package/dist/transport/binary/index.js +23 -0
- package/dist/transport/binary/tokens.js +1283 -0
- package/dist/transport/index.js +18 -0
- package/dist/transport/keepalive/WaKeepAlive.js +145 -0
- package/dist/transport/node/WaNodeOrchestrator.js +147 -0
- package/dist/transport/node/WaNodeTransport.js +68 -0
- package/dist/transport/node/builders/accountSync.js +110 -0
- package/dist/transport/node/builders/group.js +52 -0
- package/dist/transport/node/builders/index.js +39 -0
- package/dist/transport/node/builders/media.js +13 -0
- package/dist/transport/node/builders/message.js +328 -0
- package/dist/transport/node/builders/pairing.js +137 -0
- package/dist/transport/node/builders/prekeys.js +107 -0
- package/dist/transport/node/builders/retry.js +119 -0
- package/dist/transport/node/helpers.js +46 -0
- package/dist/transport/node/query.js +59 -0
- package/dist/transport/node/xml.js +42 -0
- package/dist/transport/noise/WaClientPayload.js +166 -0
- package/dist/transport/noise/WaFrameCodec.js +125 -0
- package/dist/transport/noise/WaNoiseCert.js +77 -0
- package/dist/transport/noise/WaNoiseHandshake.js +61 -0
- package/dist/transport/noise/WaNoiseSession.js +326 -0
- package/dist/transport/noise/WaNoiseSocket.js +21 -0
- package/dist/transport/noise/constants.js +11 -0
- package/dist/transport/noise/types.js +2 -0
- package/dist/transport/stream/parse.js +97 -0
- package/dist/transport/types.js +2 -0
- package/dist/types/appstate/WaAppStateCrypto.d.ts +59 -0
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +63 -0
- package/dist/types/appstate/WaAppStateSyncResponseParser.d.ts +12 -0
- package/dist/types/appstate/constants.d.ts +14 -0
- package/dist/types/appstate/index.d.ts +7 -0
- package/dist/types/appstate/store/sqlite.d.ts +21 -0
- package/dist/types/appstate/types.d.ts +66 -0
- package/dist/types/appstate/utils.d.ts +10 -0
- package/dist/types/auth/WaAuthClient.d.ts +61 -0
- package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +14 -0
- package/dist/types/auth/index.d.ts +6 -0
- package/dist/types/auth/pairing/WaPairingCodeCrypto.d.ts +17 -0
- package/dist/types/auth/pairing/WaPairingFlow.d.ts +48 -0
- package/dist/types/auth/pairing/WaQrFlow.d.ts +23 -0
- package/dist/types/auth/pairing/constants.d.ts +2 -0
- package/dist/types/auth/types.d.ts +48 -0
- package/dist/types/client/WaClient.d.ts +97 -0
- package/dist/types/client/WaClientFactory.d.ts +83 -0
- package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +48 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +60 -0
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +90 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +43 -0
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +61 -0
- package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +17 -0
- package/dist/types/client/dirty.d.ts +17 -0
- package/dist/types/client/events/chat.d.ts +3 -0
- package/dist/types/client/events/group.d.ts +7 -0
- package/dist/types/client/history-sync.d.ts +17 -0
- package/dist/types/client/incoming.d.ts +35 -0
- package/dist/types/client/index.d.ts +2 -0
- package/dist/types/client/mailbox.d.ts +12 -0
- package/dist/types/client/messages.d.ts +17 -0
- package/dist/types/client/types.d.ts +235 -0
- package/dist/types/crypto/core/constants.d.ts +1 -0
- package/dist/types/crypto/core/encoding.d.ts +11 -0
- package/dist/types/crypto/core/hkdf.d.ts +8 -0
- package/dist/types/crypto/core/index.d.ts +11 -0
- package/dist/types/crypto/core/keys.d.ts +20 -0
- package/dist/types/crypto/core/nonce.d.ts +5 -0
- package/dist/types/crypto/core/primitives.d.ts +25 -0
- package/dist/types/crypto/core/random.d.ts +8 -0
- package/dist/types/crypto/curves/Ed25519.d.ts +7 -0
- package/dist/types/crypto/curves/X25519.d.ts +8 -0
- package/dist/types/crypto/curves/constants.d.ts +2 -0
- package/dist/types/crypto/curves/types.d.ts +10 -0
- package/dist/types/crypto/index.d.ts +3 -0
- package/dist/types/crypto/math/constants.d.ts +7 -0
- package/dist/types/crypto/math/edwards.d.ts +3 -0
- package/dist/types/crypto/math/le.d.ts +2 -0
- package/dist/types/crypto/math/mod.d.ts +5 -0
- package/dist/types/crypto/math/types.d.ts +6 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/infra/log/ConsoleLogger.d.ts +11 -0
- package/dist/types/infra/log/PinoLogger.d.ts +30 -0
- package/dist/types/infra/log/types.d.ts +9 -0
- package/dist/types/infra/perf/BoundedTaskQueue.d.ts +19 -0
- package/dist/types/media/WaMediaCrypto.d.ts +12 -0
- package/dist/types/media/WaMediaTransferClient.d.ts +81 -0
- package/dist/types/media/conn.d.ts +3 -0
- package/dist/types/media/constants.d.ts +10 -0
- package/dist/types/media/index.d.ts +4 -0
- package/dist/types/media/types.d.ts +56 -0
- package/dist/types/message/WaMessageClient.d.ts +29 -0
- package/dist/types/message/ack.d.ts +5 -0
- package/dist/types/message/content.d.ts +4 -0
- package/dist/types/message/device-sent.d.ts +3 -0
- package/dist/types/message/incoming.d.ts +18 -0
- package/dist/types/message/index.d.ts +2 -0
- package/dist/types/message/padding.d.ts +2 -0
- package/dist/types/message/phash.d.ts +1 -0
- package/dist/types/message/types.d.ts +58 -0
- package/dist/types/proto.d.ts +2 -0
- package/dist/types/protocol/appstate.d.ts +34 -0
- package/dist/types/protocol/auth.d.ts +12 -0
- package/dist/types/protocol/browser.d.ts +22 -0
- package/dist/types/protocol/constants.d.ts +11 -0
- package/dist/types/protocol/defaults.d.ts +26 -0
- package/dist/types/protocol/dirty.d.ts +15 -0
- package/dist/types/protocol/group.d.ts +6 -0
- package/dist/types/protocol/index.d.ts +11 -0
- package/dist/types/protocol/jid.d.ts +19 -0
- package/dist/types/protocol/media.d.ts +15 -0
- package/dist/types/protocol/message.d.ts +16 -0
- package/dist/types/protocol/nodes.d.ts +83 -0
- package/dist/types/protocol/notification.d.ts +50 -0
- package/dist/types/protocol/stream.d.ts +60 -0
- package/dist/types/retry/constants.d.ts +21 -0
- package/dist/types/retry/index.d.ts +7 -0
- package/dist/types/retry/outbound.d.ts +4 -0
- package/dist/types/retry/parse.d.ts +3 -0
- package/dist/types/retry/reason.d.ts +2 -0
- package/dist/types/retry/replay.d.ts +30 -0
- package/dist/types/retry/types.d.ts +70 -0
- package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +31 -0
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +27 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +26 -0
- package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +39 -0
- package/dist/types/signal/api/SignalRotateKeyApi.d.ts +22 -0
- package/dist/types/signal/api/SignalSessionSyncApi.d.ts +38 -0
- package/dist/types/signal/api/codec.d.ts +3 -0
- package/dist/types/signal/api/constants.d.ts +9 -0
- package/dist/types/signal/api/prekeys.d.ts +6 -0
- package/dist/types/signal/constants.d.ts +14 -0
- package/dist/types/signal/crypto/WaAdvSignature.d.ts +7 -0
- package/dist/types/signal/crypto/constants.d.ts +5 -0
- package/dist/types/signal/group/SenderKeyChain.d.ts +11 -0
- package/dist/types/signal/group/SenderKeyCodec.d.ts +14 -0
- package/dist/types/signal/group/SenderKeyManager.d.ts +22 -0
- package/dist/types/signal/index.d.ts +12 -0
- package/dist/types/signal/registration/keygen.d.ts +5 -0
- package/dist/types/signal/registration/utils.d.ts +9 -0
- package/dist/types/signal/session/SignalProtocol.d.ts +22 -0
- package/dist/types/signal/session/SignalRatchet.d.ts +25 -0
- package/dist/types/signal/session/SignalSerializer.d.ts +6 -0
- package/dist/types/signal/session/SignalSession.d.ts +43 -0
- package/dist/types/signal/store/sqlite.d.ts +72 -0
- package/dist/types/signal/types.d.ts +110 -0
- package/dist/types/store/contracts/appstate.store.d.ts +22 -0
- package/dist/types/store/contracts/auth.store.d.ts +6 -0
- package/dist/types/store/contracts/contact.store.d.ts +14 -0
- package/dist/types/store/contracts/device-list.store.d.ts +16 -0
- package/dist/types/store/contracts/message.store.d.ts +18 -0
- package/dist/types/store/contracts/participants.store.d.ts +14 -0
- package/dist/types/store/contracts/retry.store.d.ts +11 -0
- package/dist/types/store/contracts/sender-key.store.d.ts +16 -0
- package/dist/types/store/contracts/signal.store.d.ts +31 -0
- package/dist/types/store/contracts/thread.store.d.ts +17 -0
- package/dist/types/store/createStore.d.ts +2 -0
- package/dist/types/store/index.d.ts +31 -0
- package/dist/types/store/noop.store.d.ts +10 -0
- package/dist/types/store/providers/memory/appstate.store.d.ts +21 -0
- package/dist/types/store/providers/memory/contact.store.d.ts +13 -0
- package/dist/types/store/providers/memory/device-list.store.d.ts +20 -0
- package/dist/types/store/providers/memory/message.store.d.ts +14 -0
- package/dist/types/store/providers/memory/participants.store.d.ts +18 -0
- package/dist/types/store/providers/memory/retry.store.d.ts +18 -0
- package/dist/types/store/providers/memory/sender-key.store.d.ts +28 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +51 -0
- package/dist/types/store/providers/memory/thread.store.d.ts +14 -0
- package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +12 -0
- package/dist/types/store/providers/sqlite/appstate.store.d.ts +15 -0
- package/dist/types/store/providers/sqlite/auth.store.d.ts +10 -0
- package/dist/types/store/providers/sqlite/connection.d.ts +10 -0
- package/dist/types/store/providers/sqlite/contact.store.d.ts +10 -0
- package/dist/types/store/providers/sqlite/device-list.store.d.ts +18 -0
- package/dist/types/store/providers/sqlite/message.store.d.ts +11 -0
- package/dist/types/store/providers/sqlite/migrations.d.ts +3 -0
- package/dist/types/store/providers/sqlite/participants.store.d.ts +13 -0
- package/dist/types/store/providers/sqlite/retry.store.d.ts +16 -0
- package/dist/types/store/providers/sqlite/sender-key.store.d.ts +25 -0
- package/dist/types/store/providers/sqlite/signal.store.d.ts +46 -0
- package/dist/types/store/providers/sqlite/thread.store.d.ts +11 -0
- package/dist/types/store/types.d.ts +103 -0
- package/dist/types/transport/WaComms.d.ts +61 -0
- package/dist/types/transport/WaWebSocket.d.ts +36 -0
- package/dist/types/transport/binary/constants.d.ts +49 -0
- package/dist/types/transport/binary/decoder.d.ts +3 -0
- package/dist/types/transport/binary/encoder.d.ts +3 -0
- package/dist/types/transport/binary/index.d.ts +4 -0
- package/dist/types/transport/binary/tokens.d.ts +11 -0
- package/dist/types/transport/index.d.ts +7 -0
- package/dist/types/transport/keepalive/WaKeepAlive.d.ts +39 -0
- package/dist/types/transport/node/WaNodeOrchestrator.d.ts +28 -0
- package/dist/types/transport/node/WaNodeTransport.d.ts +22 -0
- package/dist/types/transport/node/builders/accountSync.d.ts +11 -0
- package/dist/types/transport/node/builders/group.d.ts +16 -0
- package/dist/types/transport/node/builders/index.d.ts +7 -0
- package/dist/types/transport/node/builders/media.d.ts +2 -0
- package/dist/types/transport/node/builders/message.d.ts +52 -0
- package/dist/types/transport/node/builders/pairing.d.ts +18 -0
- package/dist/types/transport/node/builders/prekeys.d.ts +5 -0
- package/dist/types/transport/node/builders/retry.d.ts +18 -0
- package/dist/types/transport/node/helpers.d.ts +8 -0
- package/dist/types/transport/node/query.d.ts +10 -0
- package/dist/types/transport/node/xml.d.ts +2 -0
- package/dist/types/transport/noise/WaClientPayload.d.ts +3 -0
- package/dist/types/transport/noise/WaFrameCodec.d.ts +9 -0
- package/dist/types/transport/noise/WaNoiseCert.d.ts +1 -0
- package/dist/types/transport/noise/WaNoiseHandshake.d.ts +14 -0
- package/dist/types/transport/noise/WaNoiseSession.d.ts +33 -0
- package/dist/types/transport/noise/WaNoiseSocket.d.ts +10 -0
- package/dist/types/transport/noise/constants.d.ts +7 -0
- package/dist/types/transport/noise/types.d.ts +23 -0
- package/dist/types/transport/stream/parse.d.ts +23 -0
- package/dist/types/transport/types.d.ts +71 -0
- package/dist/types/util/async.d.ts +1 -0
- package/dist/types/util/base64.d.ts +4 -0
- package/dist/types/util/bytes.d.ts +28 -0
- package/dist/types/util/coercion.d.ts +8 -0
- package/dist/types/util/collections.d.ts +3 -0
- package/dist/types/util/primitives.d.ts +7 -0
- package/dist/types/util/runtime.d.ts +2 -0
- package/dist/types/util/signal-address.d.ts +2 -0
- package/dist/util/async.js +8 -0
- package/dist/util/base64.js +24 -0
- package/dist/util/bytes.js +291 -0
- package/dist/util/coercion.js +66 -0
- package/dist/util/collections.js +32 -0
- package/dist/util/primitives.js +37 -0
- package/dist/util/runtime.js +19 -0
- package/dist/util/signal-address.js +8 -0
- package/package.json +150 -0
- package/proto/index.d.ts +10861 -0
- package/proto/index.js +1 -0
- package/scripts/check-node-version.cjs +55 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { decodeNodeContentBase64OrBytes } from '../../transport/node/helpers.js';
|
|
2
|
+
export function decodeExactLength(value, field, expectedLength) {
|
|
3
|
+
const bytes = decodeNodeContentBase64OrBytes(value, field);
|
|
4
|
+
if (bytes.byteLength !== expectedLength) {
|
|
5
|
+
throw new Error(`${field} must be ${expectedLength} bytes`);
|
|
6
|
+
}
|
|
7
|
+
return bytes;
|
|
8
|
+
}
|
|
9
|
+
export function parseUint(bytes, field) {
|
|
10
|
+
if (bytes.byteLength === 1) {
|
|
11
|
+
return bytes[0];
|
|
12
|
+
}
|
|
13
|
+
if (bytes.byteLength === 2) {
|
|
14
|
+
return (bytes[0] << 8) | bytes[1];
|
|
15
|
+
}
|
|
16
|
+
if (bytes.byteLength === 3) {
|
|
17
|
+
return (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
|
|
18
|
+
}
|
|
19
|
+
if (bytes.byteLength === 4) {
|
|
20
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, false);
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`${field} has invalid byte length`);
|
|
23
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const SIGNAL_UPLOAD_PREKEYS_COUNT = 812;
|
|
2
|
+
export const SIGNAL_SIGNED_PREKEY_ROTATION_INTERVAL_MS = 27 * 24 * 60 * 60 * 1000;
|
|
3
|
+
export const SIGNAL_SIGNED_PREKEY_SERVER_ERROR_BACKOFF_MS = 24 * 60 * 60 * 1000;
|
|
4
|
+
export const SIGNAL_KEY_BUNDLE_TYPE_BYTES = new Uint8Array([5]);
|
|
5
|
+
export const SIGNAL_KEY_BUNDLE_TYPE_LENGTH = 1;
|
|
6
|
+
export const SIGNAL_REGISTRATION_ID_LENGTH = 4;
|
|
7
|
+
export const SIGNAL_KEY_ID_LENGTH = 3;
|
|
8
|
+
export const SIGNAL_KEY_DATA_LENGTH = 32;
|
|
9
|
+
export const SIGNAL_SIGNATURE_LENGTH = 64;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { parseIqError } from '../../transport/node/query.js';
|
|
2
|
+
export { buildMissingPreKeysFetchIq, buildPreKeyUploadIq, buildSignedPreKeyRotateIq } from '../../transport/node/builders/prekeys.js';
|
|
3
|
+
export function parsePreKeyUploadFailure(node) {
|
|
4
|
+
const error = parseIqError(node);
|
|
5
|
+
return {
|
|
6
|
+
...(error.numericCode !== undefined ? { errorCode: error.numericCode } : {}),
|
|
7
|
+
errorText: error.text
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SERIALIZED_PUB_KEY_PREFIX as CORE_SERIALIZED_PUB_KEY_PREFIX } from '../crypto/core/constants.js';
|
|
2
|
+
import { TEXT_ENCODER } from '../util/bytes.js';
|
|
3
|
+
export const SIGNAL_VERSION = 3;
|
|
4
|
+
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
|
+
export const SIGNAL_MAC_SIZE = 8;
|
|
8
|
+
export const SIGNATURE_SIZE = 64;
|
|
9
|
+
export const MAX_PREV_SESSIONS = 40;
|
|
10
|
+
export const MAX_UNUSED_KEYS = 2000;
|
|
11
|
+
export const FUTURE_MESSAGES_MAX = 2000;
|
|
12
|
+
export const SENDER_KEY_FUTURE_MESSAGES_MAX = 20000;
|
|
13
|
+
export const MESSAGE_KEY_LABEL = new Uint8Array([1]);
|
|
14
|
+
export const CHAIN_KEY_LABEL = new Uint8Array([2]);
|
|
15
|
+
export const WHISPER_GROUP_INFO = TEXT_ENCODER.encode('WhisperGroup');
|
|
16
|
+
export const SIGNAL_PREFIX = new Uint8Array(32).fill(0xff);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { ed25519VerifyRaw, importHmacKey, hmacSign, randomBytesAsync, sha512, toRawPubKey } from '../../crypto/index.js';
|
|
2
|
+
import { clampCurvePrivateKeyInPlace, montgomeryToEdwardsPublic } from '../../crypto/curves/X25519.js';
|
|
3
|
+
import { encodeExtendedPoint, scalarMultBase } from '../../crypto/math/edwards.js';
|
|
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 { concatBytes } from '../../util/bytes.js';
|
|
8
|
+
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 (signature.length !== 64) {
|
|
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
|
+
if (privateKey.length !== 32) {
|
|
25
|
+
throw new Error(`invalid curve25519 private key length ${privateKey.length}`);
|
|
26
|
+
}
|
|
27
|
+
const clampedPrivateKey = clampCurvePrivateKeyInPlace(privateKey);
|
|
28
|
+
const privateScalar = bytesToBigIntLE(clampedPrivateKey);
|
|
29
|
+
const encodedPublic = encodeExtendedPoint(scalarMultBase(privateScalar));
|
|
30
|
+
const pubKeySignBit = encodedPublic[31] & 0x80;
|
|
31
|
+
const randomSuffix = await randomBytesAsync(64);
|
|
32
|
+
const hashInput = concatBytes([
|
|
33
|
+
SIGNAL_PREFIX_SIGNATURE_RANDOM,
|
|
34
|
+
clampedPrivateKey,
|
|
35
|
+
message,
|
|
36
|
+
randomSuffix
|
|
37
|
+
]);
|
|
38
|
+
const r = modGroup(bytesToBigIntLE(await sha512(hashInput)));
|
|
39
|
+
const encodedR = encodeExtendedPoint(scalarMultBase(r));
|
|
40
|
+
const hInput = concatBytes([encodedR, encodedPublic, message]);
|
|
41
|
+
const h = modGroup(bytesToBigIntLE(await sha512(hInput)));
|
|
42
|
+
const s = modGroup(r + h * privateScalar);
|
|
43
|
+
const encodedS = bigIntToBytesLE(s, 32);
|
|
44
|
+
encodedS[31] = (encodedS[31] & 0x7f) | pubKeySignBit;
|
|
45
|
+
return concatBytes([encodedR, encodedS]);
|
|
46
|
+
}
|
|
47
|
+
export async function verifyDeviceIdentityAccountSignature(details, accountSignature, identityPublicKey, accountSignatureKey, isHosted = false) {
|
|
48
|
+
const prefix = isHosted ? ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : ADV_PREFIX_ACCOUNT_SIGNATURE;
|
|
49
|
+
const message = concatBytes([prefix, details, identityPublicKey]);
|
|
50
|
+
return verifySignalSignature(accountSignatureKey, message, accountSignature);
|
|
51
|
+
}
|
|
52
|
+
export async function generateDeviceSignature(details, identityKeyPair, accountSignatureKey, isHosted = false) {
|
|
53
|
+
const prefix = isHosted ? ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : ADV_PREFIX_DEVICE_SIGNATURE;
|
|
54
|
+
const message = concatBytes([prefix, details, identityKeyPair.pubKey, accountSignatureKey]);
|
|
55
|
+
return signSignalMessage(identityKeyPair.privKey, message);
|
|
56
|
+
}
|
|
57
|
+
export async function computeAdvIdentityHmac(secretKey, details) {
|
|
58
|
+
const key = await importHmacKey(secretKey);
|
|
59
|
+
return hmacSign(key, details);
|
|
60
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export const ADV_PREFIX_ACCOUNT_SIGNATURE = new Uint8Array([6, 0]);
|
|
6
|
+
export const ADV_PREFIX_DEVICE_SIGNATURE = new Uint8Array([6, 1]);
|
|
7
|
+
export const ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = new Uint8Array([6, 5]);
|
|
8
|
+
export const ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = new Uint8Array([6, 6]);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { hkdf, importHmacKey, hmacSign } from '../../crypto/index.js';
|
|
2
|
+
import { CHAIN_KEY_LABEL, MAX_UNUSED_KEYS, MESSAGE_KEY_LABEL, SENDER_KEY_FUTURE_MESSAGES_MAX, WHISPER_GROUP_INFO } from '../constants.js';
|
|
3
|
+
import { removeAt } from '../../util/bytes.js';
|
|
4
|
+
export async function selectMessageKey(senderKey, targetIteration) {
|
|
5
|
+
const delta = targetIteration - senderKey.iteration;
|
|
6
|
+
if (delta > SENDER_KEY_FUTURE_MESSAGES_MAX) {
|
|
7
|
+
throw new Error('sender key message is too far in future');
|
|
8
|
+
}
|
|
9
|
+
const currentUnused = senderKey.unusedMessageKeys ?? [];
|
|
10
|
+
if (delta < 0) {
|
|
11
|
+
const foundIndex = currentUnused.findIndex((entry) => entry.iteration === targetIteration);
|
|
12
|
+
if (foundIndex === -1) {
|
|
13
|
+
throw new Error('sender key message iteration is stale');
|
|
14
|
+
}
|
|
15
|
+
const messageKey = currentUnused[foundIndex];
|
|
16
|
+
const nextUnused = removeAt(currentUnused, foundIndex);
|
|
17
|
+
return {
|
|
18
|
+
messageKey,
|
|
19
|
+
updatedRecord: {
|
|
20
|
+
...senderKey,
|
|
21
|
+
unusedMessageKeys: nextUnused
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
let chainState = await createSenderChainState(senderKey.chainKey);
|
|
26
|
+
const firstDerived = await deriveSenderKeyMsgKeyFromState(senderKey.iteration, chainState);
|
|
27
|
+
chainState = firstDerived.nextState;
|
|
28
|
+
let messageKey = firstDerived.messageKey;
|
|
29
|
+
let nextUnused = currentUnused.slice();
|
|
30
|
+
if (delta > 0) {
|
|
31
|
+
let overflow = delta + currentUnused.length - MAX_UNUSED_KEYS;
|
|
32
|
+
if (overflow > 0) {
|
|
33
|
+
nextUnused = nextUnused.slice(overflow);
|
|
34
|
+
overflow -= currentUnused.length;
|
|
35
|
+
}
|
|
36
|
+
for (let iteration = senderKey.iteration + 1; iteration <= targetIteration; iteration += 1) {
|
|
37
|
+
if (overflow > 0) {
|
|
38
|
+
overflow -= 1;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
nextUnused.push(messageKey);
|
|
42
|
+
}
|
|
43
|
+
const derived = await deriveSenderKeyMsgKeyFromState(iteration, chainState);
|
|
44
|
+
chainState = derived.nextState;
|
|
45
|
+
messageKey = derived.messageKey;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
messageKey,
|
|
50
|
+
updatedRecord: {
|
|
51
|
+
...senderKey,
|
|
52
|
+
iteration: targetIteration + 1,
|
|
53
|
+
chainKey: chainState.chainKey,
|
|
54
|
+
unusedMessageKeys: nextUnused
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export async function deriveSenderKeyMsgKey(iteration, chainKey) {
|
|
59
|
+
const state = await createSenderChainState(chainKey);
|
|
60
|
+
const derived = await deriveSenderKeyMsgKeyFromState(iteration, state);
|
|
61
|
+
return {
|
|
62
|
+
nextChainKey: derived.nextState.chainKey,
|
|
63
|
+
messageKey: derived.messageKey
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async function createSenderChainState(chainKey) {
|
|
67
|
+
if (chainKey.length !== 32) {
|
|
68
|
+
throw new Error('sender key chainKey must be 32 bytes');
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
chainKey,
|
|
72
|
+
hmacKey: await importHmacKey(chainKey)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function deriveSenderKeyMsgKeyFromState(iteration, state) {
|
|
76
|
+
const nextChainRawPromise = hmacSign(state.hmacKey, CHAIN_KEY_LABEL);
|
|
77
|
+
const messageInputKeyPromise = hmacSign(state.hmacKey, MESSAGE_KEY_LABEL);
|
|
78
|
+
const [nextChainRaw, messageInputKey] = await Promise.all([
|
|
79
|
+
nextChainRawPromise,
|
|
80
|
+
messageInputKeyPromise
|
|
81
|
+
]);
|
|
82
|
+
const nextChainKey = nextChainRaw.subarray(0, 32);
|
|
83
|
+
const [nextHmacKey, messageSeed] = await Promise.all([
|
|
84
|
+
importHmacKey(nextChainKey),
|
|
85
|
+
hkdf(messageInputKey, null, WHISPER_GROUP_INFO, 50)
|
|
86
|
+
]);
|
|
87
|
+
return {
|
|
88
|
+
nextState: {
|
|
89
|
+
chainKey: nextChainKey,
|
|
90
|
+
hmacKey: nextHmacKey
|
|
91
|
+
},
|
|
92
|
+
messageKey: {
|
|
93
|
+
iteration,
|
|
94
|
+
seed: messageSeed
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readVersionedContent, toSerializedPubKey } from '../../crypto/index.js';
|
|
2
|
+
import { proto } from '../../proto.js';
|
|
3
|
+
import { SIGNATURE_SIZE, SIGNAL_GROUP_VERSION } from '../constants.js';
|
|
4
|
+
import { toBytesView } from '../../util/bytes.js';
|
|
5
|
+
export function parseDistributionPayload(payload) {
|
|
6
|
+
const body = readVersionedContent(payload, SIGNAL_GROUP_VERSION, 0);
|
|
7
|
+
const decoded = proto.SenderKeyDistributionMessage.decode(body);
|
|
8
|
+
if (decoded.id === null ||
|
|
9
|
+
decoded.id === undefined ||
|
|
10
|
+
decoded.iteration === null ||
|
|
11
|
+
decoded.iteration === undefined ||
|
|
12
|
+
decoded.chainKey === null ||
|
|
13
|
+
decoded.chainKey === undefined ||
|
|
14
|
+
decoded.signingKey === null ||
|
|
15
|
+
decoded.signingKey === undefined) {
|
|
16
|
+
throw new Error('invalid sender key distribution message');
|
|
17
|
+
}
|
|
18
|
+
const chainKey = toBytesView(decoded.chainKey);
|
|
19
|
+
if (chainKey.length !== 32) {
|
|
20
|
+
throw new Error('sender key distribution chainKey must be 32 bytes');
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
keyId: decoded.id,
|
|
24
|
+
iteration: decoded.iteration,
|
|
25
|
+
chainKey,
|
|
26
|
+
signingPublicKey: toSerializedPubKey(toBytesView(decoded.signingKey))
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function parseSenderKeyMessage(versionContentMac) {
|
|
30
|
+
const body = readVersionedContent(versionContentMac, SIGNAL_GROUP_VERSION, SIGNATURE_SIZE);
|
|
31
|
+
const decoded = proto.SenderKeyMessage.decode(body);
|
|
32
|
+
if (decoded.id === null ||
|
|
33
|
+
decoded.id === undefined ||
|
|
34
|
+
decoded.iteration === null ||
|
|
35
|
+
decoded.iteration === undefined ||
|
|
36
|
+
decoded.ciphertext === null ||
|
|
37
|
+
decoded.ciphertext === undefined) {
|
|
38
|
+
throw new Error('invalid sender key message');
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
keyId: decoded.id,
|
|
42
|
+
iteration: decoded.iteration,
|
|
43
|
+
ciphertext: toBytesView(decoded.ciphertext),
|
|
44
|
+
versionContentMac
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { aesCbcDecrypt, aesCbcEncrypt, importAesCbcKey, toSerializedPubKey, prependVersion, randomBytesAsync, randomIntAsync, X25519 } from '../../crypto/index.js';
|
|
2
|
+
import { proto } from '../../proto.js';
|
|
3
|
+
import { SIGNAL_GROUP_VERSION, SIGNATURE_SIZE } from '../constants.js';
|
|
4
|
+
import { signSignalMessage, verifySignalSignature } from '../crypto/WaAdvSignature.js';
|
|
5
|
+
import { deriveSenderKeyMsgKey, selectMessageKey } from '../group/SenderKeyChain.js';
|
|
6
|
+
import { parseDistributionPayload, parseSenderKeyMessage } from '../group/SenderKeyCodec.js';
|
|
7
|
+
import { concatBytes } from '../../util/bytes.js';
|
|
8
|
+
function extractAesCbcParams(seed) {
|
|
9
|
+
if (seed.length < 48) {
|
|
10
|
+
throw new Error('sender key message seed must be at least 48 bytes');
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
iv: seed.subarray(0, 16),
|
|
14
|
+
keyBytes: seed.subarray(16, 48)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async function aesCbcEncryptFromSeed(seed, plaintext) {
|
|
18
|
+
const { keyBytes, iv } = extractAesCbcParams(seed);
|
|
19
|
+
return aesCbcEncrypt(await importAesCbcKey(keyBytes), iv, plaintext);
|
|
20
|
+
}
|
|
21
|
+
async function aesCbcDecryptFromSeed(seed, ciphertext) {
|
|
22
|
+
const { keyBytes, iv } = extractAesCbcParams(seed);
|
|
23
|
+
return aesCbcDecrypt(await importAesCbcKey(keyBytes), iv, ciphertext);
|
|
24
|
+
}
|
|
25
|
+
export class SenderKeyManager {
|
|
26
|
+
constructor(store) {
|
|
27
|
+
this.store = store;
|
|
28
|
+
}
|
|
29
|
+
async createSenderKeyDistributionMessage(groupId, sender) {
|
|
30
|
+
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
31
|
+
const distributionProto = proto.SenderKeyDistributionMessage.encode({
|
|
32
|
+
id: senderKey.keyId,
|
|
33
|
+
iteration: senderKey.iteration,
|
|
34
|
+
chainKey: senderKey.chainKey,
|
|
35
|
+
signingKey: senderKey.signingPublicKey
|
|
36
|
+
}).finish();
|
|
37
|
+
const payload = prependVersion(distributionProto, SIGNAL_GROUP_VERSION);
|
|
38
|
+
await this.store.upsertSenderKeyDistribution({
|
|
39
|
+
groupId,
|
|
40
|
+
sender,
|
|
41
|
+
keyId: senderKey.keyId,
|
|
42
|
+
timestampMs: Date.now()
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
groupId,
|
|
46
|
+
axolotlSenderKeyDistributionMessage: payload
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
async filterParticipantsNeedingDistribution(groupId, sender, participants) {
|
|
50
|
+
if (participants.length === 0) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
54
|
+
const distributed = await this.store.getDeviceSenderKeyDistributions(groupId, participants);
|
|
55
|
+
return participants.filter((_, index) => {
|
|
56
|
+
const record = distributed[index];
|
|
57
|
+
return !record || record.keyId !== senderKey.keyId;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async markSenderKeyDistributed(groupId, sender, participants) {
|
|
61
|
+
if (participants.length === 0) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
65
|
+
const timestampMs = Date.now();
|
|
66
|
+
await this.store.upsertSenderKeyDistributions(participants.map((participant) => ({
|
|
67
|
+
groupId,
|
|
68
|
+
sender: participant,
|
|
69
|
+
keyId: senderKey.keyId,
|
|
70
|
+
timestampMs
|
|
71
|
+
})));
|
|
72
|
+
}
|
|
73
|
+
async processSenderKeyDistributionPayload(groupId, sender, payload) {
|
|
74
|
+
if (groupId.length === 0) {
|
|
75
|
+
throw new Error('sender key distribution missing groupId');
|
|
76
|
+
}
|
|
77
|
+
const parsed = parseDistributionPayload(payload);
|
|
78
|
+
const record = {
|
|
79
|
+
groupId,
|
|
80
|
+
sender,
|
|
81
|
+
keyId: parsed.keyId,
|
|
82
|
+
iteration: parsed.iteration,
|
|
83
|
+
chainKey: parsed.chainKey,
|
|
84
|
+
signingPublicKey: parsed.signingPublicKey,
|
|
85
|
+
unusedMessageKeys: []
|
|
86
|
+
};
|
|
87
|
+
await this.store.upsertSenderKey(record);
|
|
88
|
+
await this.store.upsertSenderKeyDistribution({
|
|
89
|
+
groupId,
|
|
90
|
+
sender,
|
|
91
|
+
keyId: parsed.keyId,
|
|
92
|
+
timestampMs: Date.now()
|
|
93
|
+
});
|
|
94
|
+
return record;
|
|
95
|
+
}
|
|
96
|
+
async encryptGroupMessage(groupId, sender, plaintext) {
|
|
97
|
+
const senderKey = await this.ensureSenderKey(groupId, sender);
|
|
98
|
+
if (!senderKey.signingPrivateKey) {
|
|
99
|
+
throw new Error('sender private signing key is missing');
|
|
100
|
+
}
|
|
101
|
+
const derived = await deriveSenderKeyMsgKey(senderKey.iteration, senderKey.chainKey);
|
|
102
|
+
const messagePayload = await aesCbcEncryptFromSeed(derived.messageKey.seed, plaintext);
|
|
103
|
+
const senderKeyMessage = proto.SenderKeyMessage.encode({
|
|
104
|
+
id: senderKey.keyId,
|
|
105
|
+
iteration: derived.messageKey.iteration,
|
|
106
|
+
ciphertext: messagePayload
|
|
107
|
+
}).finish();
|
|
108
|
+
const versionedContent = prependVersion(senderKeyMessage, SIGNAL_GROUP_VERSION);
|
|
109
|
+
const signature = await signSignalMessage(senderKey.signingPrivateKey, versionedContent);
|
|
110
|
+
if (signature.length !== SIGNATURE_SIZE) {
|
|
111
|
+
throw new Error(`invalid sender key signature length ${signature.length}`);
|
|
112
|
+
}
|
|
113
|
+
const ciphertext = concatBytes([versionedContent, signature]);
|
|
114
|
+
await this.store.upsertSenderKey({
|
|
115
|
+
...senderKey,
|
|
116
|
+
chainKey: derived.nextChainKey,
|
|
117
|
+
iteration: derived.messageKey.iteration + 1
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
groupId,
|
|
121
|
+
sender,
|
|
122
|
+
keyId: senderKey.keyId,
|
|
123
|
+
iteration: derived.messageKey.iteration,
|
|
124
|
+
ciphertext
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async decryptGroupMessage(payload) {
|
|
128
|
+
const parsed = parseSenderKeyMessage(payload.ciphertext);
|
|
129
|
+
const senderKey = await this.store.getDeviceSenderKey(payload.groupId, payload.sender);
|
|
130
|
+
if (!senderKey) {
|
|
131
|
+
throw new Error('missing sender key');
|
|
132
|
+
}
|
|
133
|
+
if (senderKey.keyId !== parsed.keyId) {
|
|
134
|
+
throw new Error('sender key id mismatch');
|
|
135
|
+
}
|
|
136
|
+
if (payload.keyId !== undefined &&
|
|
137
|
+
payload.keyId !== null &&
|
|
138
|
+
parsed.keyId !== payload.keyId) {
|
|
139
|
+
throw new Error('sender key id mismatch');
|
|
140
|
+
}
|
|
141
|
+
if (payload.iteration !== undefined &&
|
|
142
|
+
payload.iteration !== null &&
|
|
143
|
+
parsed.iteration !== payload.iteration) {
|
|
144
|
+
throw new Error('sender key iteration mismatch');
|
|
145
|
+
}
|
|
146
|
+
const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - SIGNATURE_SIZE);
|
|
147
|
+
const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - SIGNATURE_SIZE);
|
|
148
|
+
const validSignature = await verifySignalSignature(senderKey.signingPublicKey, signedContent, signature);
|
|
149
|
+
if (!validSignature) {
|
|
150
|
+
throw new Error('invalid sender key signature');
|
|
151
|
+
}
|
|
152
|
+
const selected = await selectMessageKey(senderKey, parsed.iteration);
|
|
153
|
+
const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
|
|
154
|
+
await this.store.upsertSenderKey(selected.updatedRecord);
|
|
155
|
+
return plaintext;
|
|
156
|
+
}
|
|
157
|
+
async ensureSenderKey(groupId, sender) {
|
|
158
|
+
const existing = await this.store.getDeviceSenderKey(groupId, sender);
|
|
159
|
+
if (existing) {
|
|
160
|
+
return existing;
|
|
161
|
+
}
|
|
162
|
+
const signingKeyPair = await X25519.generateKeyPair();
|
|
163
|
+
const created = {
|
|
164
|
+
groupId,
|
|
165
|
+
sender,
|
|
166
|
+
keyId: await randomIntAsync(1, 2147483647),
|
|
167
|
+
iteration: 0,
|
|
168
|
+
chainKey: await randomBytesAsync(32),
|
|
169
|
+
signingPublicKey: toSerializedPubKey(signingKeyPair.pubKey),
|
|
170
|
+
signingPrivateKey: signingKeyPair.privKey,
|
|
171
|
+
unusedMessageKeys: []
|
|
172
|
+
};
|
|
173
|
+
await this.store.upsertSenderKey(created);
|
|
174
|
+
return created;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { generatePreKeyPair, generateRegistrationId, generateRegistrationInfo, generateSignedPreKey } from './registration/keygen.js';
|
|
2
|
+
export { buildPreKeyUploadIq, parsePreKeyUploadFailure } from './api/prekeys.js';
|
|
3
|
+
export { SignalDigestSyncApi } from './api/SignalDigestSyncApi.js';
|
|
4
|
+
export { SignalDeviceSyncApi } from './api/SignalDeviceSyncApi.js';
|
|
5
|
+
export { SignalIdentitySyncApi } from './api/SignalIdentitySyncApi.js';
|
|
6
|
+
export { SignalMissingPreKeysSyncApi } from './api/SignalMissingPreKeysSyncApi.js';
|
|
7
|
+
export { SignalRotateKeyApi } from './api/SignalRotateKeyApi.js';
|
|
8
|
+
export { SignalSessionSyncApi } from './api/SignalSessionSyncApi.js';
|
|
9
|
+
export { SenderKeyManager } from './group/SenderKeyManager.js';
|
|
10
|
+
export { createAndStoreInitialKeys } from './registration/utils.js';
|
|
11
|
+
export { SignalProtocol } from './session/SignalProtocol.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { randomIntAsync } from '../../crypto/index.js';
|
|
2
|
+
import { toSerializedPubKey } from '../../crypto/core/keys.js';
|
|
3
|
+
import { X25519 } from '../../crypto/curves/X25519.js';
|
|
4
|
+
import { signSignalMessage } from '../crypto/WaAdvSignature.js';
|
|
5
|
+
export async function generateRegistrationInfo() {
|
|
6
|
+
return {
|
|
7
|
+
registrationId: await generateRegistrationId(),
|
|
8
|
+
identityKeyPair: await X25519.generateKeyPair()
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export async function generatePreKeyPair(keyId) {
|
|
12
|
+
return {
|
|
13
|
+
keyId,
|
|
14
|
+
keyPair: await X25519.generateKeyPair(),
|
|
15
|
+
uploaded: false
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export async function generateSignedPreKey(keyId, signingPrivateKey) {
|
|
19
|
+
const keyPair = await X25519.generateKeyPair();
|
|
20
|
+
const serializedPubKey = toSerializedPubKey(keyPair.pubKey);
|
|
21
|
+
const signature = await signSignalMessage(signingPrivateKey, serializedPubKey);
|
|
22
|
+
return {
|
|
23
|
+
keyId,
|
|
24
|
+
keyPair,
|
|
25
|
+
signature,
|
|
26
|
+
uploaded: false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export async function generateRegistrationId() {
|
|
30
|
+
return await randomIntAsync(1, 16381);
|
|
31
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { generatePreKeyPair, generateRegistrationInfo, generateSignedPreKey } from '../registration/keygen.js';
|
|
2
|
+
export async function createAndStoreInitialKeys(store) {
|
|
3
|
+
const [registrationInfo, firstPreKey] = await Promise.all([
|
|
4
|
+
generateRegistrationInfo(),
|
|
5
|
+
generatePreKeyPair(1)
|
|
6
|
+
]);
|
|
7
|
+
const signedPreKey = await generateSignedPreKey(1, registrationInfo.identityKeyPair.privKey);
|
|
8
|
+
await store.setRegistrationInfo(registrationInfo);
|
|
9
|
+
await store.setSignedPreKey(signedPreKey);
|
|
10
|
+
await store.getOrGenSinglePreKey(async () => firstPreKey);
|
|
11
|
+
return {
|
|
12
|
+
registrationInfo,
|
|
13
|
+
signedPreKey,
|
|
14
|
+
firstPreKey
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { toSerializedPubKey } from '../../crypto/index.js';
|
|
2
|
+
import { ConsoleLogger } from '../../infra/log/ConsoleLogger.js';
|
|
3
|
+
import { MAX_PREV_SESSIONS } from '../constants.js';
|
|
4
|
+
import { decryptMsg, decryptMsgFromSession, encryptMsg } from '../session/SignalRatchet.js';
|
|
5
|
+
import { deserializeMsg, deserializePkMsg, requirePreKey, requireSignedPreKey } from '../session/SignalSerializer.js';
|
|
6
|
+
import { detachSession, findMatchingSession, generateSerializedKeyPair, initiateSessionIncoming, initiateSessionOutgoing, requireLocalIdentity, toSerializedKeyPair } from '../session/SignalSession.js';
|
|
7
|
+
import { uint8Equal } from '../../util/bytes.js';
|
|
8
|
+
export class SignalProtocol {
|
|
9
|
+
constructor(store, logger = new ConsoleLogger('info')) {
|
|
10
|
+
this.store = store;
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
}
|
|
13
|
+
async hasSession(address) {
|
|
14
|
+
return this.store.hasSession(address);
|
|
15
|
+
}
|
|
16
|
+
async hasSessions(addresses) {
|
|
17
|
+
return this.store.hasSessions(addresses);
|
|
18
|
+
}
|
|
19
|
+
async establishOutgoingSession(address, remoteBundle) {
|
|
20
|
+
const [local, localOneTimeBase] = await Promise.all([
|
|
21
|
+
requireLocalIdentity(this.store),
|
|
22
|
+
generateSerializedKeyPair()
|
|
23
|
+
]);
|
|
24
|
+
const session = await initiateSessionOutgoing(local, remoteBundle, localOneTimeBase);
|
|
25
|
+
await this.store.setRemoteIdentity(address, session.remote.pubKey);
|
|
26
|
+
await this.store.setSession(address, session);
|
|
27
|
+
return session;
|
|
28
|
+
}
|
|
29
|
+
async encryptMessage(address, plaintext, expectedIdentity) {
|
|
30
|
+
const session = await this.store.getSession(address);
|
|
31
|
+
if (!session) {
|
|
32
|
+
throw new Error('signal session not found');
|
|
33
|
+
}
|
|
34
|
+
if (expectedIdentity &&
|
|
35
|
+
!uint8Equal(toSerializedPubKey(expectedIdentity), session.remote.pubKey)) {
|
|
36
|
+
throw new Error('identity mismatch');
|
|
37
|
+
}
|
|
38
|
+
const [updatedSession, encrypted] = await encryptMsg(session, plaintext);
|
|
39
|
+
await this.store.setSession(address, updatedSession);
|
|
40
|
+
if (!uint8Equal(updatedSession.remote.pubKey, session.remote.pubKey)) {
|
|
41
|
+
await this.store.setRemoteIdentity(address, updatedSession.remote.pubKey);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
...encrypted,
|
|
45
|
+
baseKey: updatedSession.aliceBaseKey
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async decryptMessage(address, envelope) {
|
|
49
|
+
const currentSession = await this.store.getSession(address);
|
|
50
|
+
let outcome;
|
|
51
|
+
if (envelope.type === 'pkmsg') {
|
|
52
|
+
const parsedPk = deserializePkMsg(envelope.ciphertext);
|
|
53
|
+
outcome = await this.decryptPkMsg(currentSession, parsedPk);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const parsed = deserializeMsg(envelope.ciphertext);
|
|
57
|
+
outcome = await this.decryptMsgInternal(currentSession, parsed);
|
|
58
|
+
}
|
|
59
|
+
const nextRemoteIdentity = outcome.newSessionInfo?.newIdentity ?? outcome.updatedSession.remote.pubKey;
|
|
60
|
+
if (!currentSession || !uint8Equal(currentSession.remote.pubKey, nextRemoteIdentity)) {
|
|
61
|
+
await this.store.setRemoteIdentity(address, nextRemoteIdentity);
|
|
62
|
+
}
|
|
63
|
+
await this.store.setSession(address, outcome.updatedSession);
|
|
64
|
+
return outcome.plaintext;
|
|
65
|
+
}
|
|
66
|
+
async decryptMsgInternal(session, parsed) {
|
|
67
|
+
return decryptMsg(session, parsed, (error, previousSessionIndex) => {
|
|
68
|
+
this.logger.debug('signal decrypt fallback session failed', {
|
|
69
|
+
previousSessionIndex,
|
|
70
|
+
message: error.message
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async decryptPkMsg(currentSession, parsed) {
|
|
75
|
+
const matchingSession = findMatchingSession(currentSession, parsed.sessionBaseKey);
|
|
76
|
+
if (matchingSession) {
|
|
77
|
+
const [updatedSession, plaintext] = await decryptMsgFromSession(matchingSession, parsed);
|
|
78
|
+
return {
|
|
79
|
+
updatedSession,
|
|
80
|
+
plaintext,
|
|
81
|
+
newSessionInfo: null
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const [local, signedPreKey, oneTimePreKey] = await Promise.all([
|
|
85
|
+
requireLocalIdentity(this.store),
|
|
86
|
+
requireSignedPreKey(this.store, parsed.localSignedPreKeyId),
|
|
87
|
+
parsed.localOneTimeKeyId === null || parsed.localOneTimeKeyId === undefined
|
|
88
|
+
? Promise.resolve(null)
|
|
89
|
+
: requirePreKey(this.store, parsed.localOneTimeKeyId)
|
|
90
|
+
]);
|
|
91
|
+
const incoming = await initiateSessionIncoming(local, parsed.remote, parsed.sessionBaseKey, {
|
|
92
|
+
signed: toSerializedKeyPair(signedPreKey.keyPair),
|
|
93
|
+
oneTime: oneTimePreKey ? toSerializedKeyPair(oneTimePreKey.keyPair) : undefined,
|
|
94
|
+
ratchet: toSerializedKeyPair(signedPreKey.keyPair)
|
|
95
|
+
});
|
|
96
|
+
const newIdentity = !currentSession || !uint8Equal(incoming.remote.pubKey, currentSession.remote.pubKey)
|
|
97
|
+
? incoming.remote.pubKey
|
|
98
|
+
: null;
|
|
99
|
+
const baseSession = currentSession
|
|
100
|
+
? {
|
|
101
|
+
...incoming,
|
|
102
|
+
prevSessions: [
|
|
103
|
+
detachSession(currentSession),
|
|
104
|
+
...currentSession.prevSessions.slice(0, MAX_PREV_SESSIONS - 1)
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
: incoming;
|
|
108
|
+
const [updatedSession, plaintext] = await decryptMsgFromSession(baseSession, parsed);
|
|
109
|
+
if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
|
|
110
|
+
await this.store.consumePreKeyById(parsed.localOneTimeKeyId);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
updatedSession,
|
|
114
|
+
plaintext,
|
|
115
|
+
newSessionInfo: {
|
|
116
|
+
newIdentity,
|
|
117
|
+
baseSession,
|
|
118
|
+
usedPreKey: parsed.localOneTimeKeyId
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|