zapo-js 0.2.0 → 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 +7 -3
- package/dist/appstate/WaAppStateCrypto.js +49 -41
- package/dist/appstate/WaAppStateSyncClient.js +79 -42
- package/dist/appstate/index.js +2 -2
- package/dist/auth/WaAuthClient.js +20 -11
- package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/auth/pairing/WaPairingFlow.js +26 -29
- package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
- package/dist/client/WaClient.js +115 -75
- package/dist/client/WaClientFactory.js +113 -30
- package/dist/client/connection/WaConnectionManager.js +4 -1
- package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
- package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
- package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
- package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
- package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
- package/dist/client/dirty.js +1 -1
- package/dist/client/events/abprops.js +43 -0
- package/dist/client/events/privacy-token.js +1 -2
- package/dist/client/events/registration.js +42 -0
- package/dist/client/incoming.js +37 -0
- package/dist/client/mailbox.js +17 -1
- package/dist/client/media.js +243 -0
- package/dist/client/messages.js +163 -86
- package/dist/crypto/core/index.js +4 -1
- package/dist/crypto/core/random.js +3 -9
- package/dist/crypto/core/xeddsa.js +57 -0
- package/dist/crypto/curves/X25519.js +18 -0
- package/dist/crypto/curves/constants.js +2 -1
- package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
- package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
- package/dist/esm/appstate/index.js +1 -1
- package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
- package/dist/esm/auth/WaAuthClient.js +17 -8
- package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
- package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
- package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
- package/dist/esm/client/WaClient.js +116 -76
- package/dist/esm/client/WaClientFactory.js +114 -31
- package/dist/esm/client/connection/WaConnectionManager.js +4 -1
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
- package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
- package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
- package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
- package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
- package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
- package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
- package/dist/esm/client/dirty.js +1 -1
- package/dist/esm/client/events/abprops.js +40 -0
- package/dist/esm/client/events/privacy-token.js +1 -2
- package/dist/esm/client/events/registration.js +39 -0
- package/dist/esm/client/incoming.js +36 -0
- package/dist/esm/client/mailbox.js +17 -1
- package/dist/esm/client/media.js +234 -0
- package/dist/esm/client/messages.js +162 -85
- package/dist/esm/crypto/core/index.js +1 -0
- package/dist/esm/crypto/core/random.js +2 -7
- package/dist/esm/crypto/core/xeddsa.js +53 -0
- package/dist/esm/crypto/curves/X25519.js +20 -2
- package/dist/esm/crypto/curves/constants.js +1 -0
- package/dist/esm/infra/perf/StoreLock.js +7 -4
- package/dist/esm/media/WaMediaCrypto.js +257 -62
- package/dist/esm/media/WaMediaTransferClient.js +47 -190
- package/dist/esm/media/constants.js +2 -0
- package/dist/esm/media/processor.js +1 -0
- package/dist/esm/message/addon-crypto.js +130 -3
- package/dist/esm/message/content.js +12 -6
- package/dist/esm/message/icdc.js +8 -8
- package/dist/esm/message/incoming.js +14 -12
- package/dist/esm/message/phash.js +32 -12
- package/dist/esm/message/reporting-token.js +3 -3
- package/dist/esm/message/use-case-secret.js +1 -1
- package/dist/esm/protocol/abprops.js +159 -0
- package/dist/esm/protocol/browser.js +14 -0
- package/dist/esm/protocol/constants.js +3 -1
- package/dist/esm/protocol/email.js +30 -0
- package/dist/esm/protocol/jid.js +44 -10
- package/dist/esm/protocol/nodes.js +6 -2
- package/dist/esm/protocol/notification.js +7 -1
- package/dist/esm/retry/reason.js +1 -1
- package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
- package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
- package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
- package/dist/esm/signal/crypto/constants.js +0 -4
- package/dist/esm/signal/encoding.js +11 -54
- package/dist/esm/signal/group/SenderKeyChain.js +3 -3
- package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
- package/dist/esm/signal/group/SenderKeyManager.js +13 -10
- package/dist/esm/signal/registration/keygen.js +2 -3
- package/dist/esm/signal/registration/utils.js +2 -2
- package/dist/esm/signal/session/SignalProtocol.js +18 -17
- 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 +6 -6
- 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/session.store.js +1 -0
- package/dist/esm/store/createStore.js +48 -12
- package/dist/esm/store/index.js +4 -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/pre-key.lock.js +27 -0
- package/dist/esm/store/locks/session.lock.js +19 -0
- package/dist/esm/store/locks/signal.lock.js +0 -24
- package/dist/esm/store/noop.store.js +20 -0
- package/dist/esm/store/providers/memory/device-list.store.js +3 -0
- 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/retry.store.js +25 -11
- package/dist/esm/store/providers/memory/session.store.js +45 -0
- package/dist/esm/store/providers/memory/signal.store.js +1 -164
- package/dist/esm/transport/WaComms.js +4 -3
- package/dist/esm/transport/WaWebSocket.js +9 -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 +17 -8
- package/dist/esm/transport/node/builders/abprops.js +20 -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/offline.js +14 -0
- 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 +19 -23
- package/dist/esm/transport/node/builders/retry.js +1 -1
- package/dist/esm/transport/node/helpers.js +24 -0
- 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/noise/WaClientPayload.js +15 -10
- 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 +12 -11
- package/dist/infra/perf/StoreLock.js +7 -4
- package/dist/media/WaMediaCrypto.js +253 -58
- package/dist/media/WaMediaTransferClient.js +50 -223
- package/dist/media/constants.js +3 -1
- package/dist/media/processor.js +2 -0
- package/dist/message/addon-crypto.js +131 -0
- package/dist/message/content.js +13 -5
- package/dist/message/icdc.js +8 -8
- package/dist/message/incoming.js +14 -12
- package/dist/message/phash.js +32 -12
- package/dist/message/reporting-token.js +2 -2
- package/dist/message/use-case-secret.js +1 -1
- package/dist/protocol/abprops.js +163 -0
- package/dist/protocol/browser.js +15 -0
- package/dist/protocol/constants.js +14 -2
- package/dist/protocol/email.js +33 -0
- package/dist/protocol/jid.js +45 -10
- package/dist/protocol/nodes.js +6 -2
- package/dist/protocol/notification.js +8 -2
- package/dist/retry/reason.js +1 -1
- package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
- package/dist/signal/api/SignalDigestSyncApi.js +8 -6
- package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
- package/dist/signal/crypto/WaAdvSignature.js +2 -50
- package/dist/signal/crypto/constants.js +1 -5
- package/dist/signal/encoding.js +11 -49
- package/dist/signal/group/SenderKeyChain.js +2 -2
- package/dist/signal/group/SenderKeyCodec.js +4 -5
- package/dist/signal/group/SenderKeyManager.js +12 -9
- package/dist/signal/registration/keygen.js +1 -2
- package/dist/signal/registration/utils.js +2 -2
- package/dist/signal/session/SignalProtocol.js +18 -17
- 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 +6 -6
- 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/session.store.js +2 -0
- package/dist/store/createStore.js +47 -11
- package/dist/store/index.js +9 -1
- package/dist/store/locks/identity.lock.js +19 -0
- package/dist/store/locks/message-secret.lock.js +20 -0
- package/dist/store/locks/pre-key.lock.js +30 -0
- package/dist/store/locks/session.lock.js +22 -0
- package/dist/store/locks/signal.lock.js +0 -24
- package/dist/store/noop.store.js +21 -1
- package/dist/store/providers/memory/device-list.store.js +3 -0
- 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/retry.store.js +24 -10
- package/dist/store/providers/memory/session.store.js +49 -0
- package/dist/store/providers/memory/signal.store.js +1 -164
- package/dist/transport/WaComms.js +4 -3
- package/dist/transport/WaWebSocket.js +9 -1
- 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 +16 -7
- package/dist/transport/node/builders/abprops.js +23 -0
- package/dist/transport/node/builders/device.js +14 -0
- package/dist/transport/node/builders/email.js +72 -0
- package/dist/transport/node/builders/offline.js +17 -0
- 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 +18 -22
- package/dist/transport/node/builders/retry.js +1 -1
- package/dist/transport/node/helpers.js +26 -0
- 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/noise/WaClientPayload.js +14 -9
- 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 +11 -10
- package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
- package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
- package/dist/types/appstate/index.d.ts +1 -1
- 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/auth/WaAuthClient.d.ts +9 -3
- package/dist/types/auth/credentials-flow.d.ts +20 -0
- 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 +40 -0
- package/dist/types/client/WaClient.d.ts +19 -8
- package/dist/types/client/WaClientFactory.d.ts +10 -4
- package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
- package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
- package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
- package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
- package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
- package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
- package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
- package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
- package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
- package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
- package/dist/types/client/dirty.d.ts +3 -1
- package/dist/types/client/events/abprops.d.ts +14 -0
- package/dist/types/client/events/registration.d.ts +17 -0
- package/dist/types/client/incoming.d.ts +6 -1
- package/dist/types/client/mailbox.d.ts +2 -0
- package/dist/types/client/media.d.ts +31 -0
- package/dist/types/client/messages.d.ts +2 -0
- package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
- package/dist/types/client/types.d.ts +100 -1
- package/dist/types/crypto/core/index.d.ts +1 -0
- package/dist/types/crypto/core/primitives.d.ts +1 -1
- package/dist/types/crypto/core/random.d.ts +1 -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 +1 -0
- package/dist/types/index.d.ts +2 -1
- 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/StoreLock.d.ts +1 -0
- package/dist/types/media/WaMediaCrypto.d.ts +15 -6
- package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
- package/dist/types/media/constants.d.ts +2 -0
- package/dist/types/media/index.d.ts +1 -0
- package/dist/types/media/processor.d.ts +28 -0
- package/dist/types/media/types.d.ts +9 -3
- package/dist/types/message/addon-crypto.d.ts +34 -3
- package/dist/types/message/content.d.ts +3 -1
- package/dist/types/message/icdc.d.ts +4 -4
- package/dist/types/message/types.d.ts +16 -24
- package/dist/types/protocol/abprops.d.ts +142 -0
- package/dist/types/protocol/browser.d.ts +1 -0
- package/dist/types/protocol/constants.d.ts +5 -1
- package/dist/types/protocol/email.d.ts +32 -0
- package/dist/types/protocol/jid.d.ts +1 -0
- package/dist/types/protocol/nodes.d.ts +4 -0
- package/dist/types/protocol/notification.d.ts +6 -0
- package/dist/types/protocol/stream.d.ts +1 -0
- package/dist/types/retry/reason.d.ts +1 -1
- package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
- package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -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/encoding.d.ts +7 -1
- package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
- package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
- package/dist/types/signal/registration/utils.d.ts +2 -1
- package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
- package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
- package/dist/types/signal/session/resolver.d.ts +4 -2
- package/dist/types/signal/types.d.ts +16 -4
- 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/session.store.d.ts +14 -0
- package/dist/types/store/contracts/signal.store.d.ts +1 -34
- package/dist/types/store/index.d.ts +9 -1
- 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/pre-key.lock.d.ts +3 -0
- package/dist/types/store/locks/session.lock.d.ts +3 -0
- package/dist/types/store/noop.store.d.ts +4 -0
- 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/retry.store.d.ts +7 -1
- package/dist/types/store/providers/memory/session.store.d.ts +21 -0
- package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
- package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
- package/dist/types/store/types.d.ts +21 -1
- package/dist/types/transport/WaWebSocket.d.ts +1 -0
- 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 +6 -2
- package/dist/types/transport/node/builders/abprops.d.ts +5 -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/offline.d.ts +2 -0
- 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/helpers.d.ts +3 -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 +1 -0
- package/dist/types/transport/types.d.ts +8 -0
- package/package.json +6 -4
- package/dist/auth/pairing/constants.js +0 -5
- package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
- package/dist/esm/auth/pairing/constants.js +0 -2
- package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
- package/dist/esm/transport/node/builders/index.js +0 -11
- package/dist/transport/node/builders/index.js +0 -51
- 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/transport/node/builders/index.d.ts +0 -11
- /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = void 0;
|
|
4
|
-
exports.verifySignalSignature = verifySignalSignature;
|
|
5
|
-
exports.signSignalMessage = signSignalMessage;
|
|
6
4
|
exports.verifyDeviceIdentityAccountSignature = verifyDeviceIdentityAccountSignature;
|
|
7
5
|
exports.generateDeviceSignature = generateDeviceSignature;
|
|
8
6
|
exports.computeAdvIdentityHmac = computeAdvIdentityHmac;
|
|
9
7
|
const _crypto_1 = require("../../crypto/index.js");
|
|
10
|
-
const X25519_1 = require("../../crypto/curves/X25519");
|
|
11
|
-
const edwards_1 = require("../../crypto/math/edwards");
|
|
12
|
-
const le_1 = require("../../crypto/math/le");
|
|
13
|
-
const mod_1 = require("../../crypto/math/mod");
|
|
14
8
|
const constants_1 = require("../crypto/constants");
|
|
15
9
|
const bytes_1 = require("../../util/bytes");
|
|
16
10
|
var constants_2 = require("../crypto/constants");
|
|
@@ -18,57 +12,15 @@ Object.defineProperty(exports, "ADV_PREFIX_ACCOUNT_SIGNATURE", { enumerable: tru
|
|
|
18
12
|
Object.defineProperty(exports, "ADV_PREFIX_DEVICE_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_DEVICE_SIGNATURE; } });
|
|
19
13
|
Object.defineProperty(exports, "ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE; } });
|
|
20
14
|
Object.defineProperty(exports, "ADV_PREFIX_HOSTED_DEVICE_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE; } });
|
|
21
|
-
async function verifySignalSignature(publicKey, message, signature) {
|
|
22
|
-
if (signature.length !== 64) {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
if ((signature[63] & 0x60) !== 0) {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
28
|
-
const signatureLastByteIndex = 63;
|
|
29
|
-
const originalSignatureLastByte = signature[signatureLastByteIndex];
|
|
30
|
-
const signBit = originalSignatureLastByte & 0x80;
|
|
31
|
-
signature[signatureLastByteIndex] = originalSignatureLastByte & 0x7f;
|
|
32
|
-
const curvePublic = (0, _crypto_1.toRawPubKey)(publicKey);
|
|
33
|
-
const edPublic = (0, X25519_1.montgomeryToEdwardsPublic)(curvePublic, signBit);
|
|
34
|
-
try {
|
|
35
|
-
return await _crypto_1.Ed25519.verify(message, signature, edPublic);
|
|
36
|
-
}
|
|
37
|
-
finally {
|
|
38
|
-
signature[signatureLastByteIndex] = originalSignatureLastByte;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async function signSignalMessage(privateKey, message) {
|
|
42
|
-
(0, bytes_1.assertByteLength)(privateKey, 32, `invalid curve25519 private key length ${privateKey.length}`);
|
|
43
|
-
const clampedPrivateKey = (0, X25519_1.clampCurvePrivateKeyInPlace)(privateKey);
|
|
44
|
-
const privateScalar = (0, le_1.bytesToBigIntLE)(clampedPrivateKey);
|
|
45
|
-
const encodedPublic = (0, edwards_1.encodeExtendedPoint)((0, edwards_1.scalarMultBase)(privateScalar));
|
|
46
|
-
const pubKeySignBit = encodedPublic[31] & 0x80;
|
|
47
|
-
const randomSuffix = await (0, _crypto_1.randomBytesAsync)(64);
|
|
48
|
-
const hashInput = (0, bytes_1.concatBytes)([
|
|
49
|
-
constants_1.SIGNAL_PREFIX_SIGNATURE_RANDOM,
|
|
50
|
-
clampedPrivateKey,
|
|
51
|
-
message,
|
|
52
|
-
randomSuffix
|
|
53
|
-
]);
|
|
54
|
-
const r = (0, mod_1.modGroup)((0, le_1.bytesToBigIntLE)(await (0, _crypto_1.sha512)(hashInput)));
|
|
55
|
-
const encodedR = (0, edwards_1.encodeExtendedPoint)((0, edwards_1.scalarMultBase)(r));
|
|
56
|
-
const hInput = (0, bytes_1.concatBytes)([encodedR, encodedPublic, message]);
|
|
57
|
-
const h = (0, mod_1.modGroup)((0, le_1.bytesToBigIntLE)(await (0, _crypto_1.sha512)(hInput)));
|
|
58
|
-
const s = (0, mod_1.modGroup)(r + h * privateScalar);
|
|
59
|
-
const encodedS = (0, le_1.bigIntToBytesLE)(s, 32);
|
|
60
|
-
encodedS[31] = (encodedS[31] & 0x7f) | pubKeySignBit;
|
|
61
|
-
return (0, bytes_1.concatBytes)([encodedR, encodedS]);
|
|
62
|
-
}
|
|
63
15
|
async function verifyDeviceIdentityAccountSignature(details, accountSignature, identityPublicKey, accountSignatureKey, isHosted = false) {
|
|
64
16
|
const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : constants_1.ADV_PREFIX_ACCOUNT_SIGNATURE;
|
|
65
17
|
const message = (0, bytes_1.concatBytes)([prefix, details, identityPublicKey]);
|
|
66
|
-
return
|
|
18
|
+
return (0, _crypto_1.xeddsaVerify)((0, _crypto_1.toRawPubKey)(accountSignatureKey), message, accountSignature);
|
|
67
19
|
}
|
|
68
20
|
async function generateDeviceSignature(details, identityKeyPair, accountSignatureKey, isHosted = false) {
|
|
69
21
|
const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : constants_1.ADV_PREFIX_DEVICE_SIGNATURE;
|
|
70
22
|
const message = (0, bytes_1.concatBytes)([prefix, details, identityKeyPair.pubKey, accountSignatureKey]);
|
|
71
|
-
return
|
|
23
|
+
return (0, _crypto_1.xeddsaSign)(identityKeyPair.privKey, message);
|
|
72
24
|
}
|
|
73
25
|
async function computeAdvIdentityHmac(secretKey, details) {
|
|
74
26
|
const key = await (0, _crypto_1.importHmacKey)(secretKey);
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE =
|
|
4
|
-
exports.SIGNAL_PREFIX_SIGNATURE_RANDOM = new Uint8Array([
|
|
5
|
-
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
6
|
-
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
7
|
-
]);
|
|
3
|
+
exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = void 0;
|
|
8
4
|
exports.ADV_PREFIX_ACCOUNT_SIGNATURE = new Uint8Array([6, 0]);
|
|
9
5
|
exports.ADV_PREFIX_DEVICE_SIGNATURE = new Uint8Array([6, 1]);
|
|
10
6
|
exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = new Uint8Array([6, 5]);
|
package/dist/signal/encoding.js
CHANGED
|
@@ -5,6 +5,11 @@ exports.decodeSignalAddressFromRow = decodeSignalAddressFromRow;
|
|
|
5
5
|
exports.decodeSignalRegistrationRow = decodeSignalRegistrationRow;
|
|
6
6
|
exports.decodeSignalPreKeyRow = decodeSignalPreKeyRow;
|
|
7
7
|
exports.decodeSignalSignedPreKeyRow = decodeSignalSignedPreKeyRow;
|
|
8
|
+
exports.encodeSignalSessionSnapshot = encodeSignalSessionSnapshot;
|
|
9
|
+
exports.encodeSignalRecvChain = encodeSignalRecvChain;
|
|
10
|
+
exports.decodeSignalMessageKey = decodeSignalMessageKey;
|
|
11
|
+
exports.decodeSignalRecvChain = decodeSignalRecvChain;
|
|
12
|
+
exports.decodeSignalSessionSnapshot = decodeSignalSessionSnapshot;
|
|
8
13
|
exports.encodeSignalSessionRecord = encodeSignalSessionRecord;
|
|
9
14
|
exports.decodeSignalSessionRecord = decodeSignalSessionRecord;
|
|
10
15
|
exports.encodeSenderKeyRecord = encodeSenderKeyRecord;
|
|
@@ -70,13 +75,7 @@ function encodeSignalSessionSnapshot(session) {
|
|
|
70
75
|
rootKey: session.rootKey,
|
|
71
76
|
previousCounter: session.prevSendChainHighestIndex,
|
|
72
77
|
senderChain: encodeSignalSendChain(session.sendChain),
|
|
73
|
-
receiverChains:
|
|
74
|
-
const src = session.recvChains;
|
|
75
|
-
const arr = new Array(src.length);
|
|
76
|
-
for (let i = 0; i < src.length; i += 1)
|
|
77
|
-
arr[i] = encodeSignalRecvChain(src[i]);
|
|
78
|
-
return arr;
|
|
79
|
-
})(),
|
|
78
|
+
receiverChains: session.recvChains,
|
|
80
79
|
pendingPreKey: session.initialExchangeInfo
|
|
81
80
|
? {
|
|
82
81
|
preKeyId: session.initialExchangeInfo.remoteOneTimeId ?? undefined,
|
|
@@ -105,20 +104,7 @@ function encodeSignalRecvChain(chain) {
|
|
|
105
104
|
index: chain.nextMsgIndex,
|
|
106
105
|
key: chain.chainKey
|
|
107
106
|
},
|
|
108
|
-
messageKeys:
|
|
109
|
-
const src = chain.unusedMsgKeys ?? [];
|
|
110
|
-
const arr = new Array(src.length);
|
|
111
|
-
for (let i = 0; i < src.length; i += 1) {
|
|
112
|
-
const messageKey = src[i];
|
|
113
|
-
arr[i] = {
|
|
114
|
-
index: messageKey.index,
|
|
115
|
-
cipherKey: messageKey.cipherKey,
|
|
116
|
-
macKey: messageKey.macKey,
|
|
117
|
-
iv: messageKey.iv
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
return arr;
|
|
121
|
-
})()
|
|
107
|
+
messageKeys: chain.unusedMsgKeys
|
|
122
108
|
};
|
|
123
109
|
}
|
|
124
110
|
function decodeSignalMessageKey(messageKey, field) {
|
|
@@ -148,13 +134,7 @@ function decodeSignalRecvChain(chain, field) {
|
|
|
148
134
|
ratchetPubKey,
|
|
149
135
|
nextMsgIndex: (0, coercion_1.asNumber)(chainKey.index, `${field}.chainKey.index`),
|
|
150
136
|
chainKey: chainKeyBytes,
|
|
151
|
-
unusedMsgKeys:
|
|
152
|
-
const src = chain.messageKeys ?? [];
|
|
153
|
-
const arr = new Array(src.length);
|
|
154
|
-
for (let i = 0; i < src.length; i += 1)
|
|
155
|
-
arr[i] = decodeSignalMessageKey(src[i], `${field}.messageKeys[${i}]`);
|
|
156
|
-
return arr;
|
|
157
|
-
})()
|
|
137
|
+
unusedMsgKeys: chain.messageKeys ?? []
|
|
158
138
|
};
|
|
159
139
|
}
|
|
160
140
|
function decodeSignalSendChain(chain, field) {
|
|
@@ -213,13 +193,7 @@ function decodeSignalSessionSnapshot(session, field) {
|
|
|
213
193
|
},
|
|
214
194
|
rootKey,
|
|
215
195
|
sendChain: decodeSignalSendChain(senderChain, `${field}.senderChain`),
|
|
216
|
-
recvChains:
|
|
217
|
-
const src = session.receiverChains ?? [];
|
|
218
|
-
const arr = new Array(src.length);
|
|
219
|
-
for (let i = 0; i < src.length; i += 1)
|
|
220
|
-
arr[i] = decodeSignalRecvChain(src[i], `${field}.receiverChains[${i}]`);
|
|
221
|
-
return arr;
|
|
222
|
-
})(),
|
|
196
|
+
recvChains: session.receiverChains ?? [],
|
|
223
197
|
initialExchangeInfo: pendingPreKey
|
|
224
198
|
? {
|
|
225
199
|
remoteOneTimeId: (0, coercion_1.asOptionalNumber)(pendingPreKey.preKeyId, `${field}.pendingPreKey.preKeyId`) ??
|
|
@@ -235,13 +209,7 @@ function decodeSignalSessionSnapshot(session, field) {
|
|
|
235
209
|
function encodeSignalSessionRecord(record) {
|
|
236
210
|
return _proto_1.proto.RecordStructure.encode({
|
|
237
211
|
currentSession: encodeSignalSessionSnapshot(record),
|
|
238
|
-
previousSessions:
|
|
239
|
-
const src = record.prevSessions;
|
|
240
|
-
const arr = new Array(src.length);
|
|
241
|
-
for (let i = 0; i < src.length; i += 1)
|
|
242
|
-
arr[i] = encodeSignalSessionSnapshot(src[i]);
|
|
243
|
-
return arr;
|
|
244
|
-
})()
|
|
212
|
+
previousSessions: record.prevSessions
|
|
245
213
|
}).finish();
|
|
246
214
|
}
|
|
247
215
|
function decodeSignalSessionRecord(raw) {
|
|
@@ -252,13 +220,7 @@ function decodeSignalSessionRecord(raw) {
|
|
|
252
220
|
const current = decodeSignalSessionSnapshot(decoded.currentSession, 'signal_sessions.currentSession');
|
|
253
221
|
return {
|
|
254
222
|
...current,
|
|
255
|
-
prevSessions:
|
|
256
|
-
const src = decoded.previousSessions ?? [];
|
|
257
|
-
const arr = new Array(src.length);
|
|
258
|
-
for (let i = 0; i < src.length; i += 1)
|
|
259
|
-
arr[i] = decodeSignalSessionSnapshot(src[i], `signal_sessions.previousSessions[${i}]`);
|
|
260
|
-
return arr;
|
|
261
|
-
})()
|
|
223
|
+
prevSessions: decoded.previousSessions ?? []
|
|
262
224
|
};
|
|
263
225
|
}
|
|
264
226
|
function encodeSenderKeyRecord(record) {
|
|
@@ -5,9 +5,9 @@ exports.deriveSenderKeyMsgKey = deriveSenderKeyMsgKey;
|
|
|
5
5
|
const _crypto_1 = require("../../crypto/index.js");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
7
7
|
const bytes_1 = require("../../util/bytes");
|
|
8
|
-
async function selectMessageKey(senderKey, targetIteration) {
|
|
8
|
+
async function selectMessageKey(senderKey, targetIteration, futureMessagesMax) {
|
|
9
9
|
const delta = targetIteration - senderKey.iteration;
|
|
10
|
-
if (delta > constants_1.SENDER_KEY_FUTURE_MESSAGES_MAX) {
|
|
10
|
+
if (delta > (futureMessagesMax ?? constants_1.SENDER_KEY_FUTURE_MESSAGES_MAX)) {
|
|
11
11
|
throw new Error('sender key message is too far in future');
|
|
12
12
|
}
|
|
13
13
|
const currentUnused = senderKey.unusedMessageKeys ?? [];
|
|
@@ -20,13 +20,12 @@ function parseDistributionPayload(payload) {
|
|
|
20
20
|
decoded.signingKey === undefined) {
|
|
21
21
|
throw new Error('invalid sender key distribution message');
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
(0, bytes_1.assertByteLength)(chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
|
|
23
|
+
(0, bytes_1.assertByteLength)(decoded.chainKey, 32, 'sender key distribution chainKey must be 32 bytes');
|
|
25
24
|
return {
|
|
26
25
|
keyId: decoded.id,
|
|
27
26
|
iteration: decoded.iteration,
|
|
28
|
-
chainKey,
|
|
29
|
-
signingPublicKey: (0, _crypto_1.toSerializedPubKey)(
|
|
27
|
+
chainKey: decoded.chainKey,
|
|
28
|
+
signingPublicKey: (0, _crypto_1.toSerializedPubKey)(decoded.signingKey)
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
31
|
function parseSenderKeyMessage(versionContentMac) {
|
|
@@ -43,7 +42,7 @@ function parseSenderKeyMessage(versionContentMac) {
|
|
|
43
42
|
return {
|
|
44
43
|
keyId: decoded.id,
|
|
45
44
|
iteration: decoded.iteration,
|
|
46
|
-
ciphertext:
|
|
45
|
+
ciphertext: decoded.ciphertext,
|
|
47
46
|
versionContentMac
|
|
48
47
|
};
|
|
49
48
|
}
|
|
@@ -7,7 +7,6 @@ const _proto_1 = require("../../proto.js");
|
|
|
7
7
|
const jid_1 = require("../../protocol/jid");
|
|
8
8
|
const constants_1 = require("../api/constants");
|
|
9
9
|
const constants_2 = require("../constants");
|
|
10
|
-
const WaAdvSignature_1 = require("../crypto/WaAdvSignature");
|
|
11
10
|
const SenderKeyChain_1 = require("../group/SenderKeyChain");
|
|
12
11
|
const SenderKeyCodec_1 = require("../group/SenderKeyCodec");
|
|
13
12
|
const bytes_1 = require("../../util/bytes");
|
|
@@ -29,9 +28,11 @@ async function aesCbcDecryptFromSeed(seed, ciphertext) {
|
|
|
29
28
|
return (0, _crypto_1.aesCbcDecrypt)(await (0, _crypto_1.importAesCbcKey)(keyBytes), iv, ciphertext);
|
|
30
29
|
}
|
|
31
30
|
class SenderKeyManager {
|
|
32
|
-
constructor(store) {
|
|
31
|
+
constructor(store, options) {
|
|
33
32
|
this.senderLock = new StoreLock_1.StoreLock();
|
|
34
33
|
this.store = store;
|
|
34
|
+
this.getFutureMessagesMax = options?.getFutureMessagesMax;
|
|
35
|
+
this.skipSignatureVerification = options?.skipSignatureVerification === true;
|
|
35
36
|
}
|
|
36
37
|
async prepareGroupEncryption(groupId, sender, plaintext) {
|
|
37
38
|
return this.runWithSenderLock(groupId, sender, async () => {
|
|
@@ -62,7 +63,7 @@ class SenderKeyManager {
|
|
|
62
63
|
ciphertext: messagePayload
|
|
63
64
|
}).finish();
|
|
64
65
|
const versionedContent = (0, _crypto_1.prependVersion)(senderKeyMessage, constants_2.SIGNAL_GROUP_VERSION);
|
|
65
|
-
const signature = await (0,
|
|
66
|
+
const signature = await (0, _crypto_1.xeddsaSign)(senderKey.signingPrivateKey, versionedContent);
|
|
66
67
|
if (signature.length !== constants_1.SIGNAL_SIGNATURE_LENGTH) {
|
|
67
68
|
throw new Error(`invalid sender key signature length ${signature.length}`);
|
|
68
69
|
}
|
|
@@ -166,13 +167,15 @@ class SenderKeyManager {
|
|
|
166
167
|
parsed.iteration !== payload.iteration) {
|
|
167
168
|
throw new Error('sender key iteration mismatch');
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
if (!this.skipSignatureVerification) {
|
|
171
|
+
const signedContent = parsed.versionContentMac.subarray(0, parsed.versionContentMac.length - constants_1.SIGNAL_SIGNATURE_LENGTH);
|
|
172
|
+
const signature = parsed.versionContentMac.subarray(parsed.versionContentMac.length - constants_1.SIGNAL_SIGNATURE_LENGTH);
|
|
173
|
+
const validSignature = await (0, _crypto_1.xeddsaVerify)((0, _crypto_1.toRawPubKey)(senderKey.signingPublicKey), signedContent, signature);
|
|
174
|
+
if (!validSignature) {
|
|
175
|
+
throw new Error('invalid sender key signature');
|
|
176
|
+
}
|
|
174
177
|
}
|
|
175
|
-
const selected = await (0, SenderKeyChain_1.selectMessageKey)(senderKey, parsed.iteration);
|
|
178
|
+
const selected = await (0, SenderKeyChain_1.selectMessageKey)(senderKey, parsed.iteration, this.getFutureMessagesMax?.());
|
|
176
179
|
// Keep decrypt + persist ordered: failed decrypt must not advance sender-key state.
|
|
177
180
|
const plaintext = await aesCbcDecryptFromSeed(selected.messageKey.seed, parsed.ciphertext);
|
|
178
181
|
await this.store.upsertSenderKey(selected.updatedRecord);
|
|
@@ -7,7 +7,6 @@ exports.generateRegistrationId = generateRegistrationId;
|
|
|
7
7
|
const _crypto_1 = require("../../crypto/index.js");
|
|
8
8
|
const keys_1 = require("../../crypto/core/keys");
|
|
9
9
|
const X25519_1 = require("../../crypto/curves/X25519");
|
|
10
|
-
const WaAdvSignature_1 = require("../crypto/WaAdvSignature");
|
|
11
10
|
async function generateRegistrationInfo() {
|
|
12
11
|
const [registrationId, identityKeyPair] = await Promise.all([
|
|
13
12
|
generateRegistrationId(),
|
|
@@ -28,7 +27,7 @@ async function generatePreKeyPair(keyId) {
|
|
|
28
27
|
async function generateSignedPreKey(keyId, signingPrivateKey) {
|
|
29
28
|
const keyPair = await X25519_1.X25519.generateKeyPair();
|
|
30
29
|
const serializedPubKey = (0, keys_1.toSerializedPubKey)(keyPair.pubKey);
|
|
31
|
-
const signature = await (0,
|
|
30
|
+
const signature = await (0, _crypto_1.xeddsaSign)(signingPrivateKey, serializedPubKey);
|
|
32
31
|
return {
|
|
33
32
|
keyId,
|
|
34
33
|
keyPair,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createAndStoreInitialKeys = createAndStoreInitialKeys;
|
|
4
4
|
const keygen_1 = require("../registration/keygen");
|
|
5
|
-
async function createAndStoreInitialKeys(store) {
|
|
5
|
+
async function createAndStoreInitialKeys(store, preKeyStore) {
|
|
6
6
|
const [registrationInfo, firstPreKey] = await Promise.all([
|
|
7
7
|
(0, keygen_1.generateRegistrationInfo)(),
|
|
8
8
|
(0, keygen_1.generatePreKeyPair)(1)
|
|
@@ -11,7 +11,7 @@ async function createAndStoreInitialKeys(store) {
|
|
|
11
11
|
// Keep writes ordered so partial commit failures don't leave split registration bootstrap state.
|
|
12
12
|
await store.setRegistrationInfo(registrationInfo);
|
|
13
13
|
await store.setSignedPreKey(signedPreKey);
|
|
14
|
-
await
|
|
14
|
+
await preKeyStore.getOrGenSinglePreKey(async () => firstPreKey);
|
|
15
15
|
return {
|
|
16
16
|
registrationInfo,
|
|
17
17
|
signedPreKey,
|
|
@@ -5,6 +5,7 @@ const _crypto_1 = require("../../crypto/index.js");
|
|
|
5
5
|
const ConsoleLogger_1 = require("../../infra/log/ConsoleLogger");
|
|
6
6
|
const StoreLock_1 = require("../../infra/perf/StoreLock");
|
|
7
7
|
const constants_1 = require("../constants");
|
|
8
|
+
const encoding_1 = require("../encoding");
|
|
8
9
|
const SignalRatchet_1 = require("../session/SignalRatchet");
|
|
9
10
|
const SignalSerializer_1 = require("../session/SignalSerializer");
|
|
10
11
|
const SignalSession_1 = require("../session/SignalSession");
|
|
@@ -16,15 +17,15 @@ function signalAddressLockKey(address) {
|
|
|
16
17
|
return `signal:${signalAddressMapKey(address)}`;
|
|
17
18
|
}
|
|
18
19
|
class SignalProtocol {
|
|
19
|
-
constructor(
|
|
20
|
-
this.
|
|
20
|
+
constructor(stores, logger = new ConsoleLogger_1.ConsoleLogger('info')) {
|
|
21
|
+
this.stores = stores;
|
|
21
22
|
this.logger = logger;
|
|
22
23
|
this.sessionMutationLock = new StoreLock_1.StoreLock();
|
|
23
24
|
}
|
|
24
25
|
async establishOutgoingSession(address, remoteBundle, options = {}) {
|
|
25
26
|
return this.runWithAddressLock(address, async () => {
|
|
26
27
|
if (options.reuseExisting) {
|
|
27
|
-
const existing = await this.
|
|
28
|
+
const existing = await this.stores.session.getSession(address);
|
|
28
29
|
if (existing) {
|
|
29
30
|
const remoteIdentity = (0, _crypto_1.toSerializedPubKey)(remoteBundle.identity);
|
|
30
31
|
if (!(0, bytes_1.uint8Equal)(existing.remote.pubKey, remoteIdentity)) {
|
|
@@ -34,13 +35,13 @@ class SignalProtocol {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
const [local, localOneTimeBase] = await Promise.all([
|
|
37
|
-
(0, SignalSession_1.requireLocalIdentity)(this.
|
|
38
|
+
(0, SignalSession_1.requireLocalIdentity)(this.stores.signal),
|
|
38
39
|
(0, SignalSession_1.generateSerializedKeyPair)()
|
|
39
40
|
]);
|
|
40
41
|
const session = await (0, SignalSession_1.initiateSessionOutgoing)(local, remoteBundle, localOneTimeBase);
|
|
41
42
|
// Keep writes ordered: a stored session without matching remote identity causes false mismatch checks.
|
|
42
|
-
await this.
|
|
43
|
-
await this.
|
|
43
|
+
await this.stores.identity.setRemoteIdentity(address, session.remote.pubKey);
|
|
44
|
+
await this.stores.session.setSession(address, session);
|
|
44
45
|
return session;
|
|
45
46
|
});
|
|
46
47
|
}
|
|
@@ -88,7 +89,7 @@ class SignalProtocol {
|
|
|
88
89
|
}
|
|
89
90
|
uniqueAddressKeys.length = uniqueAddressCount;
|
|
90
91
|
uniqueAddresses.length = uniqueAddressCount;
|
|
91
|
-
const currentSessions = await this.
|
|
92
|
+
const currentSessions = await this.stores.session.getSessionsBatch(uniqueAddresses);
|
|
92
93
|
const latestSessionByAddress = new Map();
|
|
93
94
|
for (let index = 0; index < uniqueAddressCount; index += 1) {
|
|
94
95
|
const addressKey = uniqueAddressKeys[index];
|
|
@@ -142,7 +143,7 @@ class SignalProtocol {
|
|
|
142
143
|
identityUpdates[identityIndex] = update;
|
|
143
144
|
identityIndex += 1;
|
|
144
145
|
}
|
|
145
|
-
await this.
|
|
146
|
+
await this.stores.identity.setRemoteIdentities(identityUpdates);
|
|
146
147
|
}
|
|
147
148
|
const sessionUpdates = new Array(sessionUpdatesByAddress.size);
|
|
148
149
|
let sessionIndex = 0;
|
|
@@ -150,13 +151,13 @@ class SignalProtocol {
|
|
|
150
151
|
sessionUpdates[sessionIndex] = update;
|
|
151
152
|
sessionIndex += 1;
|
|
152
153
|
}
|
|
153
|
-
await this.
|
|
154
|
+
await this.stores.session.setSessionsBatch(sessionUpdates);
|
|
154
155
|
return results;
|
|
155
156
|
});
|
|
156
157
|
}
|
|
157
158
|
async decryptMessage(address, envelope) {
|
|
158
159
|
return this.runWithAddressLock(address, async () => {
|
|
159
|
-
const currentSession = await this.
|
|
160
|
+
const currentSession = await this.stores.session.getSession(address);
|
|
160
161
|
let outcome;
|
|
161
162
|
if (envelope.type === 'pkmsg') {
|
|
162
163
|
const parsedPk = (0, SignalSerializer_1.deserializePkMsg)(envelope.ciphertext);
|
|
@@ -175,9 +176,9 @@ class SignalProtocol {
|
|
|
175
176
|
const identityChanged = !currentSession || !(0, bytes_1.uint8Equal)(currentSession.remote.pubKey, nextRemoteIdentity);
|
|
176
177
|
// Keep writes ordered for consistency with resolver identity checks.
|
|
177
178
|
if (identityChanged) {
|
|
178
|
-
await this.
|
|
179
|
+
await this.stores.identity.setRemoteIdentity(address, nextRemoteIdentity);
|
|
179
180
|
}
|
|
180
|
-
await this.
|
|
181
|
+
await this.stores.session.setSession(address, outcome.updatedSession);
|
|
181
182
|
return outcome.plaintext;
|
|
182
183
|
});
|
|
183
184
|
}
|
|
@@ -195,11 +196,11 @@ class SignalProtocol {
|
|
|
195
196
|
};
|
|
196
197
|
}
|
|
197
198
|
const [local, signedPreKey, oneTimePreKey] = await Promise.all([
|
|
198
|
-
(0, SignalSession_1.requireLocalIdentity)(this.
|
|
199
|
-
(0, SignalSerializer_1.requireSignedPreKey)(this.
|
|
199
|
+
(0, SignalSession_1.requireLocalIdentity)(this.stores.signal),
|
|
200
|
+
(0, SignalSerializer_1.requireSignedPreKey)(this.stores.signal, parsed.localSignedPreKeyId),
|
|
200
201
|
parsed.localOneTimeKeyId === null || parsed.localOneTimeKeyId === undefined
|
|
201
202
|
? Promise.resolve(null)
|
|
202
|
-
: (0, SignalSerializer_1.requirePreKey)(this.
|
|
203
|
+
: (0, SignalSerializer_1.requirePreKey)(this.stores.preKey, parsed.localOneTimeKeyId)
|
|
203
204
|
]);
|
|
204
205
|
const incoming = await (0, SignalSession_1.initiateSessionIncoming)(local, parsed.remote, parsed.sessionBaseKey, {
|
|
205
206
|
signed: (0, SignalSession_1.toSerializedKeyPair)(signedPreKey.keyPair),
|
|
@@ -213,7 +214,7 @@ class SignalProtocol {
|
|
|
213
214
|
? {
|
|
214
215
|
...incoming,
|
|
215
216
|
prevSessions: [
|
|
216
|
-
(0, SignalSession_1.detachSession)(currentSession),
|
|
217
|
+
(0, encoding_1.encodeSignalSessionSnapshot)((0, SignalSession_1.detachSession)(currentSession)),
|
|
217
218
|
...currentSession.prevSessions.slice(0, constants_1.MAX_PREV_SESSIONS - 1)
|
|
218
219
|
]
|
|
219
220
|
}
|
|
@@ -221,7 +222,7 @@ class SignalProtocol {
|
|
|
221
222
|
const [updatedSession, plaintext] = await (0, SignalRatchet_1.decryptMsgFromSession)(baseSession, parsed);
|
|
222
223
|
// Only consume one-time prekeys after successful decrypt/session materialization.
|
|
223
224
|
if (parsed.localOneTimeKeyId !== null && parsed.localOneTimeKeyId !== undefined) {
|
|
224
|
-
await this.
|
|
225
|
+
await this.stores.preKey.consumePreKeyById(parsed.localOneTimeKeyId);
|
|
225
226
|
}
|
|
226
227
|
return {
|
|
227
228
|
updatedSession,
|
|
@@ -9,6 +9,7 @@ exports.decryptMsgFromSession = decryptMsgFromSession;
|
|
|
9
9
|
const _crypto_1 = require("../../crypto/index.js");
|
|
10
10
|
const _proto_1 = require("../../proto.js");
|
|
11
11
|
const constants_1 = require("../constants");
|
|
12
|
+
const encoding_1 = require("../encoding");
|
|
12
13
|
const SignalSession_1 = require("../session/SignalSession");
|
|
13
14
|
const bytes_1 = require("../../util/bytes");
|
|
14
15
|
const primitives_1 = require("../../util/primitives");
|
|
@@ -43,7 +44,7 @@ async function selectMessageKey(chain, targetCounter) {
|
|
|
43
44
|
if (idx === -1) {
|
|
44
45
|
throw new Error('duplicate message');
|
|
45
46
|
}
|
|
46
|
-
const messageKey = unused[idx];
|
|
47
|
+
const messageKey = (0, encoding_1.decodeSignalMessageKey)(unused[idx], `unusedMsgKeys[${idx}]`);
|
|
47
48
|
const nextUnused = (0, bytes_1.removeAt)(unused, idx);
|
|
48
49
|
return {
|
|
49
50
|
messageKey,
|
|
@@ -81,7 +82,12 @@ async function selectMessageKey(chain, targetCounter) {
|
|
|
81
82
|
overflow -= 1;
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
|
-
nextUnused.push(
|
|
85
|
+
nextUnused.push({
|
|
86
|
+
index: currentMessageKey.index,
|
|
87
|
+
cipherKey: currentMessageKey.cipherKey,
|
|
88
|
+
macKey: currentMessageKey.macKey,
|
|
89
|
+
iv: currentMessageKey.iv
|
|
90
|
+
});
|
|
85
91
|
}
|
|
86
92
|
const derived = await deriveMsgKeyFromState(counter, chainState);
|
|
87
93
|
currentMessageKey = derived.messageKey;
|
|
@@ -182,13 +188,14 @@ async function decryptMsg(session, parsed, onPrevSessionDecryptError) {
|
|
|
182
188
|
}
|
|
183
189
|
catch (error) {
|
|
184
190
|
for (let i = 0; i < session.prevSessions.length; i += 1) {
|
|
185
|
-
const
|
|
191
|
+
const decodedPrev = (0, encoding_1.decodeSignalSessionSnapshot)(session.prevSessions[i], `prevSessions[${i}]`);
|
|
192
|
+
const prevSession = (0, SignalSession_1.snapshotToRecord)(decodedPrev);
|
|
186
193
|
try {
|
|
187
194
|
const [updatedPrev, plaintext] = await decryptMsgFromSession(prevSession, parsed);
|
|
188
195
|
const updatedSession = {
|
|
189
196
|
...updatedPrev,
|
|
190
197
|
prevSessions: [
|
|
191
|
-
(0, SignalSession_1.detachSession)(session),
|
|
198
|
+
(0, encoding_1.encodeSignalSessionSnapshot)((0, SignalSession_1.detachSession)(session)),
|
|
192
199
|
...session.prevSessions.slice(0, i),
|
|
193
200
|
...session.prevSessions.slice(i + 1)
|
|
194
201
|
]
|
|
@@ -215,7 +222,10 @@ async function decryptMsg(session, parsed, onPrevSessionDecryptError) {
|
|
|
215
222
|
}
|
|
216
223
|
async function decryptMsgFromSession(session, message) {
|
|
217
224
|
const ratchetPubKey = (0, _crypto_1.toSerializedPubKey)(message.ratchetPubKey);
|
|
218
|
-
const recvChainIndex = session.recvChains.findIndex((
|
|
225
|
+
const recvChainIndex = session.recvChains.findIndex((raw) => {
|
|
226
|
+
const key = raw.senderRatchetKey;
|
|
227
|
+
return key !== null && key !== undefined && (0, bytes_1.uint8Equal)(key, ratchetPubKey);
|
|
228
|
+
});
|
|
219
229
|
let selectedMessageKey;
|
|
220
230
|
let updatedSession;
|
|
221
231
|
if (recvChainIndex === -1) {
|
|
@@ -233,7 +243,7 @@ async function decryptMsgFromSession(session, message) {
|
|
|
233
243
|
selectedMessageKey = selected.messageKey;
|
|
234
244
|
const sendRatchet = await (0, SignalSession_1.calculateRatchet)(recvRatchet.rootKey, newSendRatchet, ratchetPubKey);
|
|
235
245
|
const nextRecvChains = session.recvChains.slice(-MAX_TRACKED_RECV_CHAINS);
|
|
236
|
-
nextRecvChains.push(selected.updatedChain);
|
|
246
|
+
nextRecvChains.push((0, encoding_1.encodeSignalRecvChain)(selected.updatedChain));
|
|
237
247
|
updatedSession = {
|
|
238
248
|
...session,
|
|
239
249
|
rootKey: sendRatchet.rootKey,
|
|
@@ -248,10 +258,11 @@ async function decryptMsgFromSession(session, message) {
|
|
|
248
258
|
};
|
|
249
259
|
}
|
|
250
260
|
else {
|
|
251
|
-
const
|
|
261
|
+
const decoded = (0, encoding_1.decodeSignalRecvChain)(session.recvChains[recvChainIndex], `recvChains[${recvChainIndex}]`);
|
|
262
|
+
const selected = await selectMessageKey(decoded, message.counter);
|
|
252
263
|
selectedMessageKey = selected.messageKey;
|
|
253
264
|
const nextRecvChains = session.recvChains.slice();
|
|
254
|
-
nextRecvChains[recvChainIndex] = selected.updatedChain;
|
|
265
|
+
nextRecvChains[recvChainIndex] = (0, encoding_1.encodeSignalRecvChain)(selected.updatedChain);
|
|
255
266
|
updatedSession = {
|
|
256
267
|
...session,
|
|
257
268
|
recvChains: nextRecvChains
|
|
@@ -7,7 +7,6 @@ exports.requirePreKey = requirePreKey;
|
|
|
7
7
|
const _crypto_1 = require("../../crypto/index.js");
|
|
8
8
|
const _proto_1 = require("../../proto.js");
|
|
9
9
|
const constants_1 = require("../constants");
|
|
10
|
-
const bytes_1 = require("../../util/bytes");
|
|
11
10
|
function deserializeMsg(versionContentMac) {
|
|
12
11
|
const content = (0, _crypto_1.readVersionedContent)(versionContentMac, constants_1.SIGNAL_VERSION, constants_1.SIGNAL_MAC_SIZE);
|
|
13
12
|
const parsed = _proto_1.proto.SignalMessage.decode(content);
|
|
@@ -20,9 +19,9 @@ function deserializeMsg(versionContentMac) {
|
|
|
20
19
|
throw new Error('invalid signal message');
|
|
21
20
|
}
|
|
22
21
|
return {
|
|
23
|
-
ratchetPubKey: (0, _crypto_1.toSerializedPubKey)(
|
|
22
|
+
ratchetPubKey: (0, _crypto_1.toSerializedPubKey)(parsed.ratchetKey),
|
|
24
23
|
counter: parsed.counter,
|
|
25
|
-
ciphertext:
|
|
24
|
+
ciphertext: parsed.ciphertext,
|
|
26
25
|
versionContentMac
|
|
27
26
|
};
|
|
28
27
|
}
|
|
@@ -41,14 +40,14 @@ function deserializePkMsg(versionContent) {
|
|
|
41
40
|
parsed.message === undefined) {
|
|
42
41
|
throw new Error('invalid prekey signal message');
|
|
43
42
|
}
|
|
44
|
-
const signal = deserializeMsg(
|
|
43
|
+
const signal = deserializeMsg(parsed.message);
|
|
45
44
|
return {
|
|
46
45
|
...signal,
|
|
47
46
|
remote: {
|
|
48
47
|
regId: parsed.registrationId,
|
|
49
|
-
pubKey: (0, _crypto_1.toSerializedPubKey)(
|
|
48
|
+
pubKey: (0, _crypto_1.toSerializedPubKey)(parsed.identityKey)
|
|
50
49
|
},
|
|
51
|
-
sessionBaseKey: (0, _crypto_1.toSerializedPubKey)(
|
|
50
|
+
sessionBaseKey: (0, _crypto_1.toSerializedPubKey)(parsed.baseKey),
|
|
52
51
|
localSignedPreKeyId: parsed.signedPreKeyId,
|
|
53
52
|
localOneTimeKeyId: parsed.preKeyId ?? null
|
|
54
53
|
};
|
|
@@ -12,6 +12,7 @@ exports.toSerializedKeyPair = toSerializedKeyPair;
|
|
|
12
12
|
exports.ecdh = ecdh;
|
|
13
13
|
const _crypto_1 = require("../../crypto/index.js");
|
|
14
14
|
const constants_1 = require("../constants");
|
|
15
|
+
const encoding_1 = require("../encoding");
|
|
15
16
|
const bytes_1 = require("../../util/bytes");
|
|
16
17
|
function snapshotToRecord(snapshot) {
|
|
17
18
|
return {
|
|
@@ -33,19 +34,21 @@ function findMatchingSession(session, sessionBaseKey) {
|
|
|
33
34
|
return session;
|
|
34
35
|
}
|
|
35
36
|
for (let index = 0; index < session.prevSessions.length; index += 1) {
|
|
36
|
-
const
|
|
37
|
-
if (!
|
|
38
|
-
!(0, bytes_1.uint8Equal)(previousSession.aliceBaseKey, serializedBaseKey)) {
|
|
37
|
+
const rawPrev = session.prevSessions[index];
|
|
38
|
+
if (!rawPrev.aliceBaseKey || !(0, bytes_1.uint8Equal)(rawPrev.aliceBaseKey, serializedBaseKey)) {
|
|
39
39
|
continue;
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const decoded = (0, encoding_1.decodeSignalSessionSnapshot)(rawPrev, `prevSessions[${index}]`);
|
|
42
|
+
const prevSessions = [
|
|
43
|
+
(0, encoding_1.encodeSignalSessionSnapshot)(detachSession(session))
|
|
44
|
+
];
|
|
42
45
|
for (let i = 0; i < session.prevSessions.length; i += 1) {
|
|
43
46
|
if (i !== index) {
|
|
44
47
|
prevSessions.push(session.prevSessions[i]);
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
return {
|
|
48
|
-
...
|
|
51
|
+
...decoded,
|
|
49
52
|
prevSessions
|
|
50
53
|
};
|
|
51
54
|
}
|
|
@@ -85,10 +88,9 @@ async function initiateSessionOutgoing(local, remoteBundle, localOneTimeBase) {
|
|
|
85
88
|
]);
|
|
86
89
|
const [rootKey, chainKey] = await (0, _crypto_1.hkdfSplit)(secret, null, 'WhisperText');
|
|
87
90
|
const recvChain = {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
unusedMsgKeys: []
|
|
91
|
+
senderRatchetKey: remoteRatchetKey,
|
|
92
|
+
chainKey: { index: 0, key: chainKey },
|
|
93
|
+
messageKeys: []
|
|
92
94
|
};
|
|
93
95
|
const sendRatchet = await generateSerializedKeyPair();
|
|
94
96
|
const sendRatchetResult = await calculateRatchet(rootKey, sendRatchet, remoteRatchetKey);
|