@mt-tl/server 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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/auth/handshake.d.ts +35 -0
- package/dist/auth/handshake.d.ts.map +1 -0
- package/dist/auth/handshake.js +208 -0
- package/dist/auth/handshake.js.map +1 -0
- package/dist/auth/nonce-store.d.ts +22 -0
- package/dist/auth/nonce-store.d.ts.map +1 -0
- package/dist/auth/nonce-store.js +23 -0
- package/dist/auth/nonce-store.js.map +1 -0
- package/dist/bootstrap.d.ts +36 -0
- package/dist/bootstrap.d.ts.map +1 -0
- package/dist/bootstrap.js +82 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/config.d.ts +103 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -0
- package/dist/core/context.d.ts +57 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +27 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/errors.d.ts +33 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +47 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +5 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/rpc.d.ts +83 -0
- package/dist/core/rpc.d.ts.map +1 -0
- package/dist/core/rpc.js +102 -0
- package/dist/core/rpc.js.map +1 -0
- package/dist/core/updates.d.ts +56 -0
- package/dist/core/updates.d.ts.map +1 -0
- package/dist/core/updates.js +34 -0
- package/dist/core/updates.js.map +1 -0
- package/dist/create-server.d.ts +89 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +109 -0
- package/dist/create-server.js.map +1 -0
- package/dist/crypto/aes-ige.d.ts +3 -0
- package/dist/crypto/aes-ige.d.ts.map +1 -0
- package/dist/crypto/aes-ige.js +55 -0
- package/dist/crypto/aes-ige.js.map +1 -0
- package/dist/crypto/dh.d.ts +21 -0
- package/dist/crypto/dh.d.ts.map +1 -0
- package/dist/crypto/dh.js +99 -0
- package/dist/crypto/dh.js.map +1 -0
- package/dist/crypto/hashes.d.ts +6 -0
- package/dist/crypto/hashes.d.ts.map +1 -0
- package/dist/crypto/hashes.js +14 -0
- package/dist/crypto/hashes.js.map +1 -0
- package/dist/crypto/msg-key.d.ts +15 -0
- package/dist/crypto/msg-key.d.ts.map +1 -0
- package/dist/crypto/msg-key.js +24 -0
- package/dist/crypto/msg-key.js.map +1 -0
- package/dist/crypto/rsa.d.ts +27 -0
- package/dist/crypto/rsa.d.ts.map +1 -0
- package/dist/crypto/rsa.js +50 -0
- package/dist/crypto/rsa.js.map +1 -0
- package/dist/dispatch/dispatcher.d.ts +72 -0
- package/dist/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/dispatch/dispatcher.js +503 -0
- package/dist/dispatch/dispatcher.js.map +1 -0
- package/dist/dispatch/forwarders/in-process.d.ts +12 -0
- package/dist/dispatch/forwarders/in-process.d.ts.map +1 -0
- package/dist/dispatch/forwarders/in-process.js +15 -0
- package/dist/dispatch/forwarders/in-process.js.map +1 -0
- package/dist/dispatch/forwarders/print.d.ts +14 -0
- package/dist/dispatch/forwarders/print.d.ts.map +1 -0
- package/dist/dispatch/forwarders/print.js +23 -0
- package/dist/dispatch/forwarders/print.js.map +1 -0
- package/dist/dispatch/rpc-forwarder.d.ts +14 -0
- package/dist/dispatch/rpc-forwarder.d.ts.map +1 -0
- package/dist/dispatch/rpc-forwarder.js +2 -0
- package/dist/dispatch/rpc-forwarder.js.map +1 -0
- package/dist/dispatch/types.d.ts +32 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/dispatch/types.js +23 -0
- package/dist/dispatch/types.js.map +1 -0
- package/dist/gateway.d.ts +57 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +150 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +13 -0
- package/dist/lib.js.map +1 -0
- package/dist/server/message-pipeline.d.ts +57 -0
- package/dist/server/message-pipeline.d.ts.map +1 -0
- package/dist/server/message-pipeline.js +199 -0
- package/dist/server/message-pipeline.js.map +1 -0
- package/dist/session/inbound-tracker.d.ts +118 -0
- package/dist/session/inbound-tracker.d.ts.map +1 -0
- package/dist/session/inbound-tracker.js +170 -0
- package/dist/session/inbound-tracker.js.map +1 -0
- package/dist/session/message-id.d.ts +19 -0
- package/dist/session/message-id.d.ts.map +1 -0
- package/dist/session/message-id.js +30 -0
- package/dist/session/message-id.js.map +1 -0
- package/dist/session/salts.d.ts +51 -0
- package/dist/session/salts.d.ts.map +1 -0
- package/dist/session/salts.js +132 -0
- package/dist/session/salts.js.map +1 -0
- package/dist/session/session-manager.d.ts +18 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +43 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/storage/index.d.ts +14 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +16 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory.d.ts +3 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +91 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/mongo.d.ts +3 -0
- package/dist/storage/mongo.d.ts.map +1 -0
- package/dist/storage/mongo.js +175 -0
- package/dist/storage/mongo.js.map +1 -0
- package/dist/storage/types.d.ts +85 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +3 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/testkit.d.ts +11 -0
- package/dist/testkit.d.ts.map +1 -0
- package/dist/testkit.js +17 -0
- package/dist/testkit.js.map +1 -0
- package/dist/tl/codec.d.ts +37 -0
- package/dist/tl/codec.d.ts.map +1 -0
- package/dist/tl/codec.js +297 -0
- package/dist/tl/codec.js.map +1 -0
- package/dist/tl/layered-registry.d.ts +29 -0
- package/dist/tl/layered-registry.d.ts.map +1 -0
- package/dist/tl/layered-registry.js +118 -0
- package/dist/tl/layered-registry.js.map +1 -0
- package/dist/tl/protocol.d.ts +126 -0
- package/dist/tl/protocol.d.ts.map +1 -0
- package/dist/tl/protocol.js +22 -0
- package/dist/tl/protocol.js.map +1 -0
- package/dist/tl/reader.d.ts +30 -0
- package/dist/tl/reader.d.ts.map +1 -0
- package/dist/tl/reader.js +87 -0
- package/dist/tl/reader.js.map +1 -0
- package/dist/tl/registry.d.ts +39 -0
- package/dist/tl/registry.d.ts.map +1 -0
- package/dist/tl/registry.js +52 -0
- package/dist/tl/registry.js.map +1 -0
- package/dist/tl/writer.d.ts +24 -0
- package/dist/tl/writer.d.ts.map +1 -0
- package/dist/tl/writer.js +95 -0
- package/dist/tl/writer.js.map +1 -0
- package/dist/transport/connection-registry.d.ts +31 -0
- package/dist/transport/connection-registry.d.ts.map +1 -0
- package/dist/transport/connection-registry.js +84 -0
- package/dist/transport/connection-registry.js.map +1 -0
- package/dist/transport/connection.d.ts +62 -0
- package/dist/transport/connection.d.ts.map +1 -0
- package/dist/transport/connection.js +77 -0
- package/dist/transport/connection.js.map +1 -0
- package/dist/transport/framing.d.ts +39 -0
- package/dist/transport/framing.d.ts.map +1 -0
- package/dist/transport/framing.js +212 -0
- package/dist/transport/framing.js.map +1 -0
- package/dist/transport/proxy-protocol.d.ts +23 -0
- package/dist/transport/proxy-protocol.d.ts.map +1 -0
- package/dist/transport/proxy-protocol.js +108 -0
- package/dist/transport/proxy-protocol.js.map +1 -0
- package/dist/transport/server-common.d.ts +27 -0
- package/dist/transport/server-common.d.ts.map +1 -0
- package/dist/transport/server-common.js +27 -0
- package/dist/transport/server-common.js.map +1 -0
- package/dist/transport/tcp-server.d.ts +26 -0
- package/dist/transport/tcp-server.d.ts.map +1 -0
- package/dist/transport/tcp-server.js +91 -0
- package/dist/transport/tcp-server.js.map +1 -0
- package/dist/transport/ws-server.d.ts +19 -0
- package/dist/transport/ws-server.d.ts.map +1 -0
- package/dist/transport/ws-server.js +78 -0
- package/dist/transport/ws-server.js.map +1 -0
- package/dist/update-publisher.d.ts +34 -0
- package/dist/update-publisher.d.ts.map +1 -0
- package/dist/update-publisher.js +29 -0
- package/dist/update-publisher.js.map +1 -0
- package/dist/updates/mongo-update-log.d.ts +13 -0
- package/dist/updates/mongo-update-log.d.ts.map +1 -0
- package/dist/updates/mongo-update-log.js +39 -0
- package/dist/updates/mongo-update-log.js.map +1 -0
- package/dist/updates/presence-binder.d.ts +29 -0
- package/dist/updates/presence-binder.d.ts.map +1 -0
- package/dist/updates/presence-binder.js +36 -0
- package/dist/updates/presence-binder.js.map +1 -0
- package/dist/updates/presence.d.ts +31 -0
- package/dist/updates/presence.d.ts.map +1 -0
- package/dist/updates/presence.js +44 -0
- package/dist/updates/presence.js.map +1 -0
- package/dist/updates/push.d.ts +25 -0
- package/dist/updates/push.d.ts.map +1 -0
- package/dist/updates/push.js +72 -0
- package/dist/updates/push.js.map +1 -0
- package/dist/updates/redis-bus.d.ts +45 -0
- package/dist/updates/redis-bus.d.ts.map +1 -0
- package/dist/updates/redis-bus.js +59 -0
- package/dist/updates/redis-bus.js.map +1 -0
- package/dist/updates/redis-presence.d.ts +43 -0
- package/dist/updates/redis-presence.d.ts.map +1 -0
- package/dist/updates/redis-presence.js +65 -0
- package/dist/updates/redis-presence.js.map +1 -0
- package/dist/updates/render.d.ts +16 -0
- package/dist/updates/render.d.ts.map +1 -0
- package/dist/updates/render.js +46 -0
- package/dist/updates/render.js.map +1 -0
- package/dist/updates/router.d.ts +27 -0
- package/dist/updates/router.d.ts.map +1 -0
- package/dist/updates/router.js +36 -0
- package/dist/updates/router.js.map +1 -0
- package/dist/updates/types.d.ts +23 -0
- package/dist/updates/types.d.ts.map +1 -0
- package/dist/updates/types.js +2 -0
- package/dist/updates/types.js.map +1 -0
- package/dist/updates/update-bus.d.ts +29 -0
- package/dist/updates/update-bus.d.ts.map +1 -0
- package/dist/updates/update-bus.js +24 -0
- package/dist/updates/update-bus.js.map +1 -0
- package/dist/util/bytes.d.ts +12 -0
- package/dist/util/bytes.d.ts.map +1 -0
- package/dist/util/bytes.js +46 -0
- package/dist/util/bytes.js.map +1 -0
- package/package.json +84 -0
- package/src/auth/handshake.ts +262 -0
- package/src/auth/nonce-store.ts +39 -0
- package/src/bootstrap.ts +114 -0
- package/src/config.ts +103 -0
- package/src/core/context.ts +94 -0
- package/src/core/errors.ts +52 -0
- package/src/core/index.ts +4 -0
- package/src/core/rpc.ts +165 -0
- package/src/core/updates.ts +69 -0
- package/src/create-server.ts +181 -0
- package/src/crypto/aes-ige.ts +57 -0
- package/src/crypto/dh.ts +101 -0
- package/src/crypto/hashes.ts +17 -0
- package/src/crypto/msg-key.ts +29 -0
- package/src/crypto/rsa.ts +70 -0
- package/src/dispatch/dispatcher.ts +586 -0
- package/src/dispatch/forwarders/in-process.ts +14 -0
- package/src/dispatch/forwarders/print.ts +22 -0
- package/src/dispatch/rpc-forwarder.ts +15 -0
- package/src/dispatch/types.ts +60 -0
- package/src/gateway.ts +214 -0
- package/src/index.ts +53 -0
- package/src/lib.ts +24 -0
- package/src/server/message-pipeline.ts +256 -0
- package/src/session/inbound-tracker.ts +221 -0
- package/src/session/message-id.ts +43 -0
- package/src/session/salts.ts +162 -0
- package/src/session/session-manager.ts +66 -0
- package/src/storage/index.ts +26 -0
- package/src/storage/memory.ts +101 -0
- package/src/storage/mongo.ts +215 -0
- package/src/storage/types.ts +92 -0
- package/src/testkit.ts +19 -0
- package/src/tl/codec.ts +292 -0
- package/src/tl/layered-registry.ts +132 -0
- package/src/tl/protocol.ts +146 -0
- package/src/tl/reader.ts +99 -0
- package/src/tl/registry.ts +78 -0
- package/src/tl/writer.ts +104 -0
- package/src/transport/connection-registry.ts +91 -0
- package/src/transport/connection.ts +113 -0
- package/src/transport/framing.ts +223 -0
- package/src/transport/proxy-protocol.ts +109 -0
- package/src/transport/server-common.ts +49 -0
- package/src/transport/tcp-server.ts +102 -0
- package/src/transport/ws-server.ts +94 -0
- package/src/update-publisher.ts +47 -0
- package/src/updates/mongo-update-log.ts +49 -0
- package/src/updates/presence-binder.ts +51 -0
- package/src/updates/presence.ts +61 -0
- package/src/updates/push.ts +90 -0
- package/src/updates/redis-bus.ts +86 -0
- package/src/updates/redis-presence.ts +87 -0
- package/src/updates/render.ts +53 -0
- package/src/updates/router.ts +52 -0
- package/src/updates/types.ts +24 -0
- package/src/updates/update-bus.ts +49 -0
- package/src/util/bytes.ts +49 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { bootstrap } from './lib.js';
|
|
2
|
+
import { createLogger, } from '@mt-tl/tl';
|
|
3
|
+
import { RpcRegistry, dispatchRpc, LoggingUpdateEmitter, } from './core/index.js';
|
|
4
|
+
const noopEmitter = { async emit() { }, async emitToAuthKey() { } };
|
|
5
|
+
/**
|
|
6
|
+
* Creates an MTProto server (Fastify-style). Pass the {@link MTProtoConfig},
|
|
7
|
+
* register routes with `.method()` / plugins with `.register()`, then
|
|
8
|
+
* `await app.listen()`. The framework owns the whole protocol — transport,
|
|
9
|
+
* handshake, crypto, sessions, TL (de)serialization, layered encoding,
|
|
10
|
+
* server-push — you write methods.
|
|
11
|
+
*
|
|
12
|
+
* Type it with your generated `RpcMethods` (`createServer<RpcMethods>(config)`)
|
|
13
|
+
* so every route's name, `params`, and `result` are checked.
|
|
14
|
+
*
|
|
15
|
+
* @param config - the server configuration (your app builds it from env).
|
|
16
|
+
* @param opts.registry - adopt an existing {@link RpcRegistry} instead of a fresh one (advanced/tests).
|
|
17
|
+
* @param opts.migrations - per-layer migration ladders applied on input/output.
|
|
18
|
+
* @param opts.logger - structured logger; defaults to `createLogger({ name: config.nodeId })`
|
|
19
|
+
* (env-configured via `LOG_LEVEL`/`LOG_FORMAT`). Exposed as `app.log`; handlers get `ctx.log`.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const app = createServer<RpcMethods>(config)
|
|
24
|
+
* app.method('help.getConfig', { auth: false }, async () => ({ _: 'config' }))
|
|
25
|
+
* await app.listen() // opens the WS + raw-TCP carriers
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function createServer(config, opts = {}) {
|
|
29
|
+
const registry = opts.registry ?? new RpcRegistry();
|
|
30
|
+
const logger = opts.logger ?? createLogger({ name: config.nodeId });
|
|
31
|
+
let gateway;
|
|
32
|
+
let emitter = noopEmitter;
|
|
33
|
+
const app = {
|
|
34
|
+
method(name, optsOrHandler, maybeHandler) {
|
|
35
|
+
const handler = (maybeHandler ?? optsOrHandler);
|
|
36
|
+
const methodOpts = maybeHandler ? optsOrHandler : {};
|
|
37
|
+
registry.add({
|
|
38
|
+
[name]: {
|
|
39
|
+
auth: methodOpts.auth ?? true,
|
|
40
|
+
preHandlers: methodOpts.preHandlers,
|
|
41
|
+
handler,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
return app;
|
|
45
|
+
},
|
|
46
|
+
register(plugin, deps) {
|
|
47
|
+
plugin(app, deps);
|
|
48
|
+
return app;
|
|
49
|
+
},
|
|
50
|
+
async listen() {
|
|
51
|
+
if (gateway)
|
|
52
|
+
throw new Error('server already listening');
|
|
53
|
+
gateway = await bootstrap({
|
|
54
|
+
config,
|
|
55
|
+
migrations: opts.migrations,
|
|
56
|
+
logger,
|
|
57
|
+
createForward: (publish, updateLog) => {
|
|
58
|
+
// Handler-emitted updates (ctx.push / ctx.updates) flow to the push loop,
|
|
59
|
+
// logged (for pts) via the shared update log bootstrap provides.
|
|
60
|
+
emitter = new LoggingUpdateEmitter(updateLog, publish);
|
|
61
|
+
return req => dispatchRpc(registry, req, { updates: emitter, logger });
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
await gateway.listen();
|
|
65
|
+
},
|
|
66
|
+
async close() {
|
|
67
|
+
await gateway?.close();
|
|
68
|
+
},
|
|
69
|
+
inject(req) {
|
|
70
|
+
return dispatchRpc(registry, req, { updates: emitter, logger });
|
|
71
|
+
},
|
|
72
|
+
get log() {
|
|
73
|
+
return logger;
|
|
74
|
+
},
|
|
75
|
+
get methods() {
|
|
76
|
+
return registry.methods();
|
|
77
|
+
},
|
|
78
|
+
get wsPort() {
|
|
79
|
+
return gateway?.wsServer?.port;
|
|
80
|
+
},
|
|
81
|
+
get tcpPort() {
|
|
82
|
+
return gateway?.tcpServer?.port;
|
|
83
|
+
},
|
|
84
|
+
get publicKey() {
|
|
85
|
+
return gateway?.publicKey;
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
return app;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Authoring helper for a typed plugin — a function that registers a group of
|
|
92
|
+
* related routes, taking its dependencies by value (Style-A DI, like
|
|
93
|
+
* `fastify.register`). Pin it to your `RpcMethods` once (see your app's
|
|
94
|
+
* `framework.ts`) so routes inside infer their types.
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* export const walletsPlugin = definePlugin<RpcMethods, { wallets: WalletService }>(
|
|
99
|
+
* (app, { wallets }) => {
|
|
100
|
+
* app.method('wallets.getBalance', async (_p, ctx) => wallets.balanceOf(ctx.subject!))
|
|
101
|
+
* },
|
|
102
|
+
* )
|
|
103
|
+
* app.register(walletsPlugin, { wallets: new WalletService() })
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export function definePlugin(fn) {
|
|
107
|
+
return fn;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=create-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-ige.d.ts","sourceRoot":"","sources":["../../src/crypto/aes-ige.ts"],"names":[],"mappings":"AAgBA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAmBxE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAmBxE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* AES-256 in IGE (Infinite Garble Extension) mode, as used by MTProto.
|
|
4
|
+
*
|
|
5
|
+
* Reimplemented on Node's `aes-256-ecb` (the existing server used CryptoJS's
|
|
6
|
+
* IGE). Verified byte-identical against the old lib via a known-answer test.
|
|
7
|
+
* Input length must be a multiple of 16; IV is 32 bytes (two blocks).
|
|
8
|
+
*/
|
|
9
|
+
function xor16(a, b) {
|
|
10
|
+
const out = Buffer.allocUnsafe(16);
|
|
11
|
+
for (let i = 0; i < 16; i++)
|
|
12
|
+
out[i] = a[i] ^ b[i];
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
export function igeEncrypt(data, key, iv) {
|
|
16
|
+
if (data.length % 16 !== 0)
|
|
17
|
+
throw new Error('IGE: data length must be a multiple of 16');
|
|
18
|
+
if (iv.length !== 32)
|
|
19
|
+
throw new Error('IGE: iv must be 32 bytes');
|
|
20
|
+
const cipher = createCipheriv('aes-256-ecb', key, null);
|
|
21
|
+
cipher.setAutoPadding(false);
|
|
22
|
+
let prevCipher = iv.subarray(0, 16);
|
|
23
|
+
let prevPlain = iv.subarray(16, 32);
|
|
24
|
+
const out = Buffer.allocUnsafe(data.length);
|
|
25
|
+
for (let i = 0; i < data.length; i += 16) {
|
|
26
|
+
const block = data.subarray(i, i + 16);
|
|
27
|
+
const enc = cipher.update(xor16(block, prevCipher));
|
|
28
|
+
const c = xor16(enc, prevPlain);
|
|
29
|
+
c.copy(out, i);
|
|
30
|
+
prevCipher = c;
|
|
31
|
+
prevPlain = Buffer.from(block);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
export function igeDecrypt(data, key, iv) {
|
|
36
|
+
if (data.length % 16 !== 0)
|
|
37
|
+
throw new Error('IGE: data length must be a multiple of 16');
|
|
38
|
+
if (iv.length !== 32)
|
|
39
|
+
throw new Error('IGE: iv must be 32 bytes');
|
|
40
|
+
const decipher = createDecipheriv('aes-256-ecb', key, null);
|
|
41
|
+
decipher.setAutoPadding(false);
|
|
42
|
+
let prevCipher = iv.subarray(0, 16);
|
|
43
|
+
let prevPlain = iv.subarray(16, 32);
|
|
44
|
+
const out = Buffer.allocUnsafe(data.length);
|
|
45
|
+
for (let i = 0; i < data.length; i += 16) {
|
|
46
|
+
const block = Buffer.from(data.subarray(i, i + 16));
|
|
47
|
+
const dec = decipher.update(xor16(block, prevPlain));
|
|
48
|
+
const p = xor16(dec, prevCipher);
|
|
49
|
+
p.copy(out, i);
|
|
50
|
+
prevCipher = block;
|
|
51
|
+
prevPlain = p;
|
|
52
|
+
}
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=aes-ige.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-ige.js","sourceRoot":"","sources":["../../src/crypto/aes-ige.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diffie-Hellman parameters and helpers for the auth-key exchange.
|
|
3
|
+
* The 2048-bit prime and generator are the exact values the existing server
|
|
4
|
+
* uses (`libs/mtproto-tools`), required for wire-compatibility.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DH_PRIME: Buffer<ArrayBuffer>;
|
|
7
|
+
export declare const DH_PRIME_BIGINT: bigint;
|
|
8
|
+
export declare const DH_G = 3;
|
|
9
|
+
export declare function modPow(base: bigint, exp: bigint, mod: bigint): bigint;
|
|
10
|
+
/** MTProto padding: smallest r >= 0 with (a + r) divisible by b. */
|
|
11
|
+
export declare function calculatePadding(a: number, b: number, min?: number): number;
|
|
12
|
+
/**
|
|
13
|
+
* Returns [p, q, pq] where p < q are ~31-bit primes and pq = p*q fits in a
|
|
14
|
+
* signed 64-bit long. Mirrors the existing server's `makePQ`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function makePQ(): {
|
|
17
|
+
p: bigint;
|
|
18
|
+
q: bigint;
|
|
19
|
+
pq: Buffer;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=dh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dh.d.ts","sourceRoot":"","sources":["../../src/crypto/dh.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,QAAQ,qBAUpB,CAAA;AACD,eAAO,MAAM,eAAe,QAAuB,CAAA;AACnD,eAAO,MAAM,IAAI,IAAI,CAAA;AAErB,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAUrE;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,MAAM,CAItE;AA6CD;;;GAGG;AACH,wBAAgB,MAAM,IAAI;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAY7D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { toBigIntBE } from '../util/bytes.js';
|
|
3
|
+
/**
|
|
4
|
+
* Diffie-Hellman parameters and helpers for the auth-key exchange.
|
|
5
|
+
* The 2048-bit prime and generator are the exact values the existing server
|
|
6
|
+
* uses (`libs/mtproto-tools`), required for wire-compatibility.
|
|
7
|
+
*/
|
|
8
|
+
export const DH_PRIME = Buffer.from('C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F' +
|
|
9
|
+
'48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C37' +
|
|
10
|
+
'20FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F64' +
|
|
11
|
+
'2477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4' +
|
|
12
|
+
'A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754' +
|
|
13
|
+
'FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4' +
|
|
14
|
+
'E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F' +
|
|
15
|
+
'0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5B', 'hex');
|
|
16
|
+
export const DH_PRIME_BIGINT = toBigIntBE(DH_PRIME);
|
|
17
|
+
export const DH_G = 3;
|
|
18
|
+
export function modPow(base, exp, mod) {
|
|
19
|
+
let result = 1n;
|
|
20
|
+
let b = base % mod;
|
|
21
|
+
let e = exp;
|
|
22
|
+
while (e > 0n) {
|
|
23
|
+
if (e & 1n)
|
|
24
|
+
result = (result * b) % mod;
|
|
25
|
+
e >>= 1n;
|
|
26
|
+
b = (b * b) % mod;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
/** MTProto padding: smallest r >= 0 with (a + r) divisible by b. */
|
|
31
|
+
export function calculatePadding(a, b, min = 0) {
|
|
32
|
+
let r = -a % b;
|
|
33
|
+
while (r < 0 || (min && r < min))
|
|
34
|
+
r += b;
|
|
35
|
+
return r + 0; // normalize -0 -> 0
|
|
36
|
+
}
|
|
37
|
+
// --- p, q factorization proof-of-work --------------------------------------
|
|
38
|
+
const MAX_INT = 0x7fffffffn;
|
|
39
|
+
const MAX_LONG = 0x7fffffffffffffffn;
|
|
40
|
+
const MR_WITNESSES = [2n, 3n, 5n, 7n, 11n, 13n, 17n, 19n, 23n, 29n, 31n, 37n];
|
|
41
|
+
function isProbablePrime(n) {
|
|
42
|
+
if (n < 2n)
|
|
43
|
+
return false;
|
|
44
|
+
for (const p of MR_WITNESSES) {
|
|
45
|
+
if (n === p)
|
|
46
|
+
return true;
|
|
47
|
+
if (n % p === 0n)
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
let d = n - 1n;
|
|
51
|
+
let r = 0n;
|
|
52
|
+
while ((d & 1n) === 0n) {
|
|
53
|
+
d >>= 1n;
|
|
54
|
+
r++;
|
|
55
|
+
}
|
|
56
|
+
for (const a of MR_WITNESSES) {
|
|
57
|
+
let x = modPow(a, d, n);
|
|
58
|
+
if (x === 1n || x === n - 1n)
|
|
59
|
+
continue;
|
|
60
|
+
let composite = true;
|
|
61
|
+
for (let i = 0n; i < r - 1n; i++) {
|
|
62
|
+
x = (x * x) % n;
|
|
63
|
+
if (x === n - 1n) {
|
|
64
|
+
composite = false;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (composite)
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
function randomPrime31() {
|
|
74
|
+
for (;;) {
|
|
75
|
+
let n = BigInt(randomBytes(4).readUInt32BE(0) & 0x7fffffff);
|
|
76
|
+
n |= 1n;
|
|
77
|
+
if (n < 3n || n > MAX_INT)
|
|
78
|
+
continue;
|
|
79
|
+
if (isProbablePrime(n))
|
|
80
|
+
return n;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Returns [p, q, pq] where p < q are ~31-bit primes and pq = p*q fits in a
|
|
85
|
+
* signed 64-bit long. Mirrors the existing server's `makePQ`.
|
|
86
|
+
*/
|
|
87
|
+
export function makePQ() {
|
|
88
|
+
let a;
|
|
89
|
+
let b;
|
|
90
|
+
let ab;
|
|
91
|
+
do {
|
|
92
|
+
a = randomPrime31();
|
|
93
|
+
b = randomPrime31();
|
|
94
|
+
ab = a * b;
|
|
95
|
+
} while (a > MAX_INT || b > MAX_INT || ab > MAX_LONG);
|
|
96
|
+
const pq = Buffer.from(ab.toString(16).padStart(16, '0'), 'hex');
|
|
97
|
+
return a < b ? { p: a, q: b, pq } : { p: b, q: a, pq };
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=dh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dh.js","sourceRoot":"","sources":["../../src/crypto/dh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { xorBuffers } from '../util/bytes.js';
|
|
2
|
+
export declare function sha1(buf: Buffer): Buffer;
|
|
3
|
+
export declare function sha256(buf: Buffer): Buffer;
|
|
4
|
+
/** Cryptographically-random bigint of the given bit width (multiple of 8). */
|
|
5
|
+
export declare function randomBigInt(bits: number): bigint;
|
|
6
|
+
//# sourceMappingURL=hashes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hashes.d.ts","sourceRoot":"","sources":["../../src/crypto/hashes.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
import { toBigIntBE } from '../util/bytes.js';
|
|
3
|
+
export { xorBuffers } from '../util/bytes.js';
|
|
4
|
+
export function sha1(buf) {
|
|
5
|
+
return createHash('sha1').update(buf).digest();
|
|
6
|
+
}
|
|
7
|
+
export function sha256(buf) {
|
|
8
|
+
return createHash('sha256').update(buf).digest();
|
|
9
|
+
}
|
|
10
|
+
/** Cryptographically-random bigint of the given bit width (multiple of 8). */
|
|
11
|
+
export function randomBigInt(bits) {
|
|
12
|
+
return toBigIntBE(randomBytes(bits / 8));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=hashes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hashes.js","sourceRoot":"","sources":["../../src/crypto/hashes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,MAAM,UAAU,IAAI,CAAC,GAAW;IAC5B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAA;AACpD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,IAAY;IACrC,OAAO,UAAU,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAA;AAC5C,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MTProto 2.0 message-key derivation. `outgoing` selects the key half
|
|
3
|
+
* (server->client uses x=8). Ported from the existing `messageEncryption.js`;
|
|
4
|
+
* pinned by a known-answer test.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateMessageKey(authKey: Buffer, msgKey: Buffer, outgoing: boolean): {
|
|
7
|
+
aesKey: Buffer;
|
|
8
|
+
aesIv: Buffer;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* msg_key = SHA256(authKey[88+x : 88+x+32] ‖ plaintext)[8:24] (MTProto 2.0),
|
|
12
|
+
* where x = 8 for server->client (outgoing) and x = 0 for client->server.
|
|
13
|
+
*/
|
|
14
|
+
export declare function computeMsgKey(authKey: Buffer, plaintext: Buffer, outgoing: boolean): Buffer;
|
|
15
|
+
//# sourceMappingURL=msg-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-key.d.ts","sourceRoot":"","sources":["../../src/crypto/msg-key.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,OAAO,GAClB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAQnC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAG3F"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { sha256 } from './hashes.js';
|
|
2
|
+
/**
|
|
3
|
+
* MTProto 2.0 message-key derivation. `outgoing` selects the key half
|
|
4
|
+
* (server->client uses x=8). Ported from the existing `messageEncryption.js`;
|
|
5
|
+
* pinned by a known-answer test.
|
|
6
|
+
*/
|
|
7
|
+
export function generateMessageKey(authKey, msgKey, outgoing) {
|
|
8
|
+
const x = outgoing ? 8 : 0;
|
|
9
|
+
const a = sha256(Buffer.concat([msgKey, authKey.subarray(x, x + 36)]));
|
|
10
|
+
const b = sha256(Buffer.concat([authKey.subarray(x + 40, x + 76), msgKey]));
|
|
11
|
+
return {
|
|
12
|
+
aesKey: Buffer.concat([a.subarray(0, 8), b.subarray(8, 24), a.subarray(24, 32)]),
|
|
13
|
+
aesIv: Buffer.concat([b.subarray(0, 8), a.subarray(8, 24), b.subarray(24, 32)]),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* msg_key = SHA256(authKey[88+x : 88+x+32] ‖ plaintext)[8:24] (MTProto 2.0),
|
|
18
|
+
* where x = 8 for server->client (outgoing) and x = 0 for client->server.
|
|
19
|
+
*/
|
|
20
|
+
export function computeMsgKey(authKey, plaintext, outgoing) {
|
|
21
|
+
const x = outgoing ? 8 : 0;
|
|
22
|
+
return sha256(Buffer.concat([authKey.subarray(88 + x, 88 + x + 32), plaintext])).subarray(8, 24);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=msg-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-key.js","sourceRoot":"","sources":["../../src/crypto/msg-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAC9B,OAAe,EACf,MAAc,EACd,QAAiB;IAEjB,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IACtE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3E,OAAO;QACH,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAChF,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;KAClF,CAAA;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,SAAiB,EAAE,QAAiB;IAC/E,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACpG,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type KeyObject } from 'node:crypto';
|
|
2
|
+
export interface RsaKeyPair {
|
|
3
|
+
privateKey: KeyObject;
|
|
4
|
+
publicKey: KeyObject;
|
|
5
|
+
/** Lower-64-bit key fingerprint advertised to clients in resPQ. */
|
|
6
|
+
fingerprint: bigint;
|
|
7
|
+
fingerprintBuf: Buffer;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Telegram RSA fingerprint: take the bare TL serialization of the public key
|
|
11
|
+
* (modulus `n` and exponent `e` as `bytes`), SHA1 it, and use the last 8 bytes.
|
|
12
|
+
*/
|
|
13
|
+
export declare function computeFingerprint(publicKey: KeyObject): {
|
|
14
|
+
fingerprint: bigint;
|
|
15
|
+
buf: Buffer;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Loads the gateway's RSA key pair. With `pemPath` set, the operator-provided
|
|
19
|
+
* production key is used (its fingerprint must match what clients have pinned).
|
|
20
|
+
* Without it, an ephemeral 2048-bit key is generated for local dev/testing.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadRsaKeyPair(pemPath?: string): RsaKeyPair;
|
|
23
|
+
/** RSA decrypt of the client's `encrypted_data` with no padding (raw 256 bytes). */
|
|
24
|
+
export declare function rsaDecryptNoPadding(privateKey: KeyObject, encryptedData: Buffer): Buffer;
|
|
25
|
+
/** RSA encrypt with no padding — used only by the test client. */
|
|
26
|
+
export declare function rsaEncryptNoPadding(publicKey: KeyObject, data: Buffer): Buffer;
|
|
27
|
+
//# sourceMappingURL=rsa.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsa.d.ts","sourceRoot":"","sources":["../../src/crypto/rsa.ts"],"names":[],"mappings":"AAAA,OAAO,EAOH,KAAK,SAAS,EACjB,MAAM,aAAa,CAAA;AAMpB,MAAM,WAAW,UAAU;IACvB,UAAU,EAAE,SAAS,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;IACpB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAU7F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAgB3D;AAED,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAExF;AAED,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { constants, createPrivateKey, createPublicKey, generateKeyPairSync, privateDecrypt, publicEncrypt, } from 'node:crypto';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { TlWriter } from '../tl/writer.js';
|
|
4
|
+
import { sha1 } from './hashes.js';
|
|
5
|
+
import { toBigIntLE } from '../util/bytes.js';
|
|
6
|
+
/**
|
|
7
|
+
* Telegram RSA fingerprint: take the bare TL serialization of the public key
|
|
8
|
+
* (modulus `n` and exponent `e` as `bytes`), SHA1 it, and use the last 8 bytes.
|
|
9
|
+
*/
|
|
10
|
+
export function computeFingerprint(publicKey) {
|
|
11
|
+
const jwk = publicKey.export({ format: 'jwk' });
|
|
12
|
+
const n = Buffer.from(jwk.n, 'base64url');
|
|
13
|
+
const e = Buffer.from(jwk.e, 'base64url');
|
|
14
|
+
const w = new TlWriter();
|
|
15
|
+
w.writeBytes(n);
|
|
16
|
+
w.writeBytes(e);
|
|
17
|
+
const digest = sha1(w.toBuffer());
|
|
18
|
+
const buf = digest.subarray(12, 20);
|
|
19
|
+
return { fingerprint: toBigIntLE(buf), buf: Buffer.from(buf) };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Loads the gateway's RSA key pair. With `pemPath` set, the operator-provided
|
|
23
|
+
* production key is used (its fingerprint must match what clients have pinned).
|
|
24
|
+
* Without it, an ephemeral 2048-bit key is generated for local dev/testing.
|
|
25
|
+
*/
|
|
26
|
+
export function loadRsaKeyPair(pemPath) {
|
|
27
|
+
let privateKey;
|
|
28
|
+
let publicKey;
|
|
29
|
+
if (pemPath) {
|
|
30
|
+
const pem = readFileSync(pemPath, 'utf-8');
|
|
31
|
+
privateKey = createPrivateKey(pem);
|
|
32
|
+
publicKey = createPublicKey(privateKey);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const pair = generateKeyPairSync('rsa', { modulusLength: 2048 });
|
|
36
|
+
privateKey = pair.privateKey;
|
|
37
|
+
publicKey = pair.publicKey;
|
|
38
|
+
}
|
|
39
|
+
const { fingerprint, buf } = computeFingerprint(publicKey);
|
|
40
|
+
return { privateKey, publicKey, fingerprint, fingerprintBuf: buf };
|
|
41
|
+
}
|
|
42
|
+
/** RSA decrypt of the client's `encrypted_data` with no padding (raw 256 bytes). */
|
|
43
|
+
export function rsaDecryptNoPadding(privateKey, encryptedData) {
|
|
44
|
+
return privateDecrypt({ key: privateKey, padding: constants.RSA_NO_PADDING }, encryptedData);
|
|
45
|
+
}
|
|
46
|
+
/** RSA encrypt with no padding — used only by the test client. */
|
|
47
|
+
export function rsaEncryptNoPadding(publicKey, data) {
|
|
48
|
+
return publicEncrypt({ key: publicKey, padding: constants.RSA_NO_PADDING }, data);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=rsa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsa.js","sourceRoot":"","sources":["../../src/crypto/rsa.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,GAEhB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAU7C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAoB;IACnD,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAA6B,CAAA;IAC3E,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;IACzC,MAAM,CAAC,GAAG,IAAI,QAAQ,EAAE,CAAA;IACxB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IACf,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IACf,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACnC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAA;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC3C,IAAI,UAAqB,CAAA;IACzB,IAAI,SAAoB,CAAA;IAExB,IAAI,OAAO,EAAE,CAAC;QACV,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC1C,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAClC,SAAS,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;IAC3C,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,GAAG,mBAAmB,CAAC,KAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QAChE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QAC5B,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;IAC9B,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;IAC1D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,EAAE,CAAA;AACtE,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,mBAAmB,CAAC,UAAqB,EAAE,aAAqB;IAC5E,OAAO,cAAc,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,aAAa,CAAC,CAAA;AAChG,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,mBAAmB,CAAC,SAAoB,EAAE,IAAY;IAClE,OAAO,aAAa,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,CAAA;AACrF,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { TlCodec } from '../tl/codec.js';
|
|
2
|
+
import type { TlRegistry } from '../tl/registry.js';
|
|
3
|
+
import { MigrationRegistry } from '@mt-tl/tl';
|
|
4
|
+
import type { Connection } from '../transport/connection.js';
|
|
5
|
+
import type { Storage } from '../storage/index.js';
|
|
6
|
+
import type { SaltService } from '../session/salts.js';
|
|
7
|
+
import { type MessageContext, type Responder } from './types.js';
|
|
8
|
+
import type { RpcForwarder } from './rpc-forwarder.js';
|
|
9
|
+
import type { PresenceBinder } from '../updates/presence-binder.js';
|
|
10
|
+
import type { UpdateLog } from '../core/updates.js';
|
|
11
|
+
import { type Logger } from '@mt-tl/tl';
|
|
12
|
+
export interface DispatcherDeps {
|
|
13
|
+
codec: TlCodec;
|
|
14
|
+
registry: TlRegistry;
|
|
15
|
+
storage: Storage;
|
|
16
|
+
saltService: SaltService;
|
|
17
|
+
responder: Responder;
|
|
18
|
+
forwarder: RpcForwarder;
|
|
19
|
+
/** Presence/registry binder; defaults to a no-op (push disabled). */
|
|
20
|
+
binder?: PresenceBinder;
|
|
21
|
+
/** Per-predicate migration ladders; defaults to empty (identity). */
|
|
22
|
+
migrations?: MigrationRegistry;
|
|
23
|
+
/** Observability sink; defaults to a no-op logger. */
|
|
24
|
+
logger?: Logger;
|
|
25
|
+
/** Disable inbound seqno validation for container-inner messages (mirrors the
|
|
26
|
+
* pipeline's `disableSeqNoCheck`); default enforced. */
|
|
27
|
+
disableSeqNoCheck?: boolean;
|
|
28
|
+
/** Durable pts log for protocol-managed `updates.getState`/`getDifference`. */
|
|
29
|
+
updateLog?: UpdateLog;
|
|
30
|
+
/** When true (+ `updateLog`), answer getState/getDifference in-engine. */
|
|
31
|
+
managedUpdates?: boolean;
|
|
32
|
+
/** Whitelist of accepted `initConnection.api_id`s; omitted → any id is accepted. */
|
|
33
|
+
allowedApiIds?: Iterable<number>;
|
|
34
|
+
}
|
|
35
|
+
export declare class Dispatcher {
|
|
36
|
+
private readonly deps;
|
|
37
|
+
private readonly binder;
|
|
38
|
+
private readonly migrations;
|
|
39
|
+
private readonly logger;
|
|
40
|
+
private readonly checkSeqNo;
|
|
41
|
+
private readonly managedUpdates;
|
|
42
|
+
/** Built once from `deps.allowedApiIds`; undefined = whitelist disabled. */
|
|
43
|
+
private readonly allowedApiIds?;
|
|
44
|
+
constructor(deps: DispatcherDeps);
|
|
45
|
+
/** Entry point: a raw message body (after the encrypted envelope). */
|
|
46
|
+
dispatchPayload(payload: Buffer, ctx: MessageContext, conn: Connection): Promise<void>;
|
|
47
|
+
private dispatchObject;
|
|
48
|
+
/**
|
|
49
|
+
* Process an `initConnection` envelope: optionally enforce the `api_id`
|
|
50
|
+
* whitelist, then capture the device/app fields onto the connection and
|
|
51
|
+
* persist them to the auth key's meta (the per-device source of truth; an
|
|
52
|
+
* auth key is one app install, so this is stable per key, not per session).
|
|
53
|
+
* Returns `true` when the connection was rejected (caller must not dispatch
|
|
54
|
+
* the wrapped query).
|
|
55
|
+
*/
|
|
56
|
+
private handleInitConnection;
|
|
57
|
+
/**
|
|
58
|
+
* Engine-owned `updates.getState` / `updates.getDifference` (when
|
|
59
|
+
* `config.updates.managed`). Common pts sequence only — qts/seq/channels are 0.
|
|
60
|
+
* Updates are returned in `other_updates`; the durable {@link UpdateLog}
|
|
61
|
+
* supplies pts. Auth-gated like a normal `auth: true` method.
|
|
62
|
+
*/
|
|
63
|
+
private handleManagedUpdate;
|
|
64
|
+
private handleService;
|
|
65
|
+
private forwardBusiness;
|
|
66
|
+
/** Apply backend-requested mutations to gateway-owned auth/session state. */
|
|
67
|
+
private applyEffects;
|
|
68
|
+
private patchSession;
|
|
69
|
+
private sendRpcResult;
|
|
70
|
+
private sendRpcError;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAoB,iBAAiB,EAA+C,MAAM,WAAW,CAAA;AAC5G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,EAAoB,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAElF,OAAO,KAAK,EAAE,YAAY,EAA6B,MAAM,oBAAoB,CAAA;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AAsCnD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,UAAU,CAAA;IACpB,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,WAAW,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,YAAY,CAAA;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,qEAAqE;IACrE,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;6DACyD;IACzD,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,+EAA+E;IAC/E,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,oFAAoF;IACpF,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;CACnC;AAED,qBAAa,UAAU;IASP,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAqB;gBAEvB,IAAI,EAAE,cAAc;IASjD,sEAAsE;IAChE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAwE9E,cAAc;IAsC5B;;;;;;;OAOG;YACW,oBAAoB;IAmClC;;;;;OAKG;YACW,mBAAmB;YA+CnB,aAAa;YAoGb,eAAe;IAgF7B,6EAA6E;YAC/D,YAAY;YA6BZ,YAAY;IAS1B,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,YAAY;CAOvB"}
|