@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.11
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 +749 -2
- package/dist/client/abort.d.ts +5 -0
- package/dist/client/abort.d.ts.map +1 -0
- package/dist/client/abort.js +23 -0
- package/dist/client/abort.js.map +1 -0
- package/dist/client/address.d.ts +17 -0
- package/dist/client/address.d.ts.map +1 -0
- package/dist/client/address.js +66 -0
- package/dist/client/address.js.map +1 -0
- package/dist/client/api/avatars.d.ts +65 -0
- package/dist/client/api/avatars.d.ts.map +1 -0
- package/dist/client/api/avatars.js +118 -0
- package/dist/client/api/avatars.js.map +1 -0
- package/dist/client/api/voice.d.ts +59 -0
- package/dist/client/api/voice.d.ts.map +1 -0
- package/dist/client/api/voice.js +110 -0
- package/dist/client/api/voice.js.map +1 -0
- package/dist/client/capabilities.d.ts +68 -0
- package/dist/client/capabilities.d.ts.map +1 -0
- package/dist/client/capabilities.js +59 -0
- package/dist/client/capabilities.js.map +1 -0
- package/dist/client/client.d.ts +235 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1666 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/commands.d.ts +66 -0
- package/dist/client/commands.d.ts.map +1 -0
- package/dist/client/commands.js +168 -0
- package/dist/client/commands.js.map +1 -0
- package/dist/client/connection-info.d.ts +14 -0
- package/dist/client/connection-info.d.ts.map +1 -0
- package/dist/client/connection-info.js +47 -0
- package/dist/client/connection-info.js.map +1 -0
- package/dist/client/crypto/crypt-ops.d.ts +7 -0
- package/dist/client/crypto/crypt-ops.d.ts.map +1 -0
- package/dist/client/crypto/crypt-ops.js +2 -0
- package/dist/client/crypto/crypt-ops.js.map +1 -0
- package/dist/client/crypto/crypt.d.ts +37 -0
- package/dist/client/crypto/crypt.d.ts.map +1 -0
- package/dist/client/crypto/crypt.js +203 -0
- package/dist/client/crypto/crypt.js.map +1 -0
- package/dist/client/crypto/eax.d.ts +12 -0
- package/dist/client/crypto/eax.d.ts.map +1 -0
- package/dist/client/crypto/eax.js +118 -0
- package/dist/client/crypto/eax.js.map +1 -0
- package/dist/client/crypto/identity.d.ts +97 -0
- package/dist/client/crypto/identity.d.ts.map +1 -0
- package/dist/client/crypto/identity.js +412 -0
- package/dist/client/crypto/identity.js.map +1 -0
- package/dist/client/crypto/index.d.ts +7 -0
- package/dist/client/crypto/index.d.ts.map +1 -0
- package/dist/client/crypto/index.js +5 -0
- package/dist/client/crypto/index.js.map +1 -0
- package/dist/client/crypto/primitives.d.ts +43 -0
- package/dist/client/crypto/primitives.d.ts.map +1 -0
- package/dist/client/crypto/primitives.js +116 -0
- package/dist/client/crypto/primitives.js.map +1 -0
- package/dist/client/diagnostics.d.ts +45 -0
- package/dist/client/diagnostics.d.ts.map +1 -0
- package/dist/client/diagnostics.js +30 -0
- package/dist/client/diagnostics.js.map +1 -0
- package/dist/client/discovery/index.d.ts +2 -0
- package/dist/client/discovery/index.d.ts.map +1 -0
- package/dist/client/discovery/index.js +2 -0
- package/dist/client/discovery/index.js.map +1 -0
- package/dist/client/discovery/resolver.d.ts +26 -0
- package/dist/client/discovery/resolver.d.ts.map +1 -0
- package/dist/client/discovery/resolver.js +275 -0
- package/dist/client/discovery/resolver.js.map +1 -0
- package/dist/client/errors.d.ts +82 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +201 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/events.d.ts +3 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +8 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/handshake/crypt-handshake.d.ts +17 -0
- package/dist/client/handshake/crypt-handshake.d.ts.map +1 -0
- package/dist/client/handshake/crypt-handshake.js +128 -0
- package/dist/client/handshake/crypt-handshake.js.map +1 -0
- package/dist/client/handshake/crypt-init2.d.ts +7 -0
- package/dist/client/handshake/crypt-init2.d.ts.map +1 -0
- package/dist/client/handshake/crypt-init2.js +37 -0
- package/dist/client/handshake/crypt-init2.js.map +1 -0
- package/dist/client/handshake/index.d.ts +4 -0
- package/dist/client/handshake/index.d.ts.map +1 -0
- package/dist/client/handshake/index.js +4 -0
- package/dist/client/handshake/index.js.map +1 -0
- package/dist/client/handshake/license.d.ts +35 -0
- package/dist/client/handshake/license.d.ts.map +1 -0
- package/dist/client/handshake/license.js +169 -0
- package/dist/client/handshake/license.js.map +1 -0
- package/dist/client/handshake.d.ts +27 -0
- package/dist/client/handshake.d.ts.map +1 -0
- package/dist/client/handshake.js +126 -0
- package/dist/client/handshake.js.map +1 -0
- package/dist/client/helpers.d.ts +6 -0
- package/dist/client/helpers.d.ts.map +1 -0
- package/dist/client/helpers.js +13 -0
- package/dist/client/helpers.js.map +1 -0
- package/dist/client/hooks.d.ts +7 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +28 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +28 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +29 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/reconnect.d.ts +12 -0
- package/dist/client/reconnect.d.ts.map +1 -0
- package/dist/client/reconnect.js +44 -0
- package/dist/client/reconnect.js.map +1 -0
- package/dist/client/throttle.d.ts +20 -0
- package/dist/client/throttle.d.ts.map +1 -0
- package/dist/client/throttle.js +83 -0
- package/dist/client/throttle.js.map +1 -0
- package/dist/client/trace.d.ts +223 -0
- package/dist/client/trace.d.ts.map +1 -0
- package/dist/client/trace.js +13 -0
- package/dist/client/trace.js.map +1 -0
- package/dist/client/transfer.d.ts +111 -0
- package/dist/client/transfer.d.ts.map +1 -0
- package/dist/client/transfer.js +243 -0
- package/dist/client/transfer.js.map +1 -0
- package/dist/client/transport/generation-window.d.ts +30 -0
- package/dist/client/transport/generation-window.d.ts.map +1 -0
- package/dist/client/transport/generation-window.js +97 -0
- package/dist/client/transport/generation-window.js.map +1 -0
- package/dist/client/transport/handler.d.ts +79 -0
- package/dist/client/transport/handler.d.ts.map +1 -0
- package/dist/client/transport/handler.js +868 -0
- package/dist/client/transport/handler.js.map +1 -0
- package/dist/client/transport/index.d.ts +6 -0
- package/dist/client/transport/index.d.ts.map +1 -0
- package/dist/client/transport/index.js +5 -0
- package/dist/client/transport/index.js.map +1 -0
- package/dist/client/transport/packet.d.ts +36 -0
- package/dist/client/transport/packet.d.ts.map +1 -0
- package/dist/client/transport/packet.js +55 -0
- package/dist/client/transport/packet.js.map +1 -0
- package/dist/client/transport/quicklz.d.ts +24 -0
- package/dist/client/transport/quicklz.d.ts.map +1 -0
- package/dist/client/transport/quicklz.js +179 -0
- package/dist/client/transport/quicklz.js.map +1 -0
- package/dist/client/transport/traffic.d.ts +43 -0
- package/dist/client/transport/traffic.d.ts.map +1 -0
- package/dist/client/transport/traffic.js +90 -0
- package/dist/client/transport/traffic.js.map +1 -0
- package/dist/client/types.d.ts +402 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +113 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/view.d.ts +162 -0
- package/dist/client/view.d.ts.map +1 -0
- package/dist/client/view.js +228 -0
- package/dist/client/view.js.map +1 -0
- package/dist/core/api/avatars.d.ts +26 -0
- package/dist/core/api/avatars.d.ts.map +1 -0
- package/dist/core/api/avatars.js +37 -0
- package/dist/core/api/avatars.js.map +1 -0
- package/dist/core/api/channels.d.ts +191 -0
- package/dist/core/api/channels.d.ts.map +1 -0
- package/dist/core/api/channels.js +174 -0
- package/dist/core/api/channels.js.map +1 -0
- package/dist/core/api/clients.d.ts +562 -0
- package/dist/core/api/clients.d.ts.map +1 -0
- package/dist/core/api/clients.js +435 -0
- package/dist/core/api/clients.js.map +1 -0
- package/dist/core/api/command.d.ts +400 -0
- package/dist/core/api/command.d.ts.map +1 -0
- package/dist/core/api/command.js +462 -0
- package/dist/core/api/command.js.map +1 -0
- package/dist/core/api/credentials.d.ts +186 -0
- package/dist/core/api/credentials.d.ts.map +1 -0
- package/dist/core/api/credentials.js +144 -0
- package/dist/core/api/credentials.js.map +1 -0
- package/dist/core/api/files.d.ts +153 -0
- package/dist/core/api/files.d.ts.map +1 -0
- package/dist/core/api/files.js +185 -0
- package/dist/core/api/files.js.map +1 -0
- package/dist/core/api/groups.d.ts +301 -0
- package/dist/core/api/groups.d.ts.map +1 -0
- package/dist/core/api/groups.js +339 -0
- package/dist/core/api/groups.js.map +1 -0
- package/dist/core/api/icons.d.ts +67 -0
- package/dist/core/api/icons.d.ts.map +1 -0
- package/dist/core/api/icons.js +125 -0
- package/dist/core/api/icons.js.map +1 -0
- package/dist/core/api/instance.d.ts +197 -0
- package/dist/core/api/instance.d.ts.map +1 -0
- package/dist/core/api/instance.js +160 -0
- package/dist/core/api/instance.js.map +1 -0
- package/dist/core/api/moderation.d.ts +266 -0
- package/dist/core/api/moderation.d.ts.map +1 -0
- package/dist/core/api/moderation.js +258 -0
- package/dist/core/api/moderation.js.map +1 -0
- package/dist/core/api/parse.d.ts +36 -0
- package/dist/core/api/parse.d.ts.map +1 -0
- package/dist/core/api/parse.js +109 -0
- package/dist/core/api/parse.js.map +1 -0
- package/dist/core/api/server.d.ts +334 -0
- package/dist/core/api/server.d.ts.map +1 -0
- package/dist/core/api/server.js +324 -0
- package/dist/core/api/server.js.map +1 -0
- package/dist/core/channel-tree.d.ts +87 -0
- package/dist/core/channel-tree.d.ts.map +1 -0
- package/dist/core/channel-tree.js +378 -0
- package/dist/core/channel-tree.js.map +1 -0
- package/dist/core/command/command.d.ts +20 -0
- package/dist/core/command/command.d.ts.map +1 -0
- package/dist/core/command/command.js +112 -0
- package/dist/core/command/command.js.map +1 -0
- package/dist/core/command/ids.d.ts +131 -0
- package/dist/core/command/ids.d.ts.map +1 -0
- package/dist/core/command/ids.js +87 -0
- package/dist/core/command/ids.js.map +1 -0
- package/dist/core/command/parser.d.ts +17 -0
- package/dist/core/command/parser.d.ts.map +1 -0
- package/dist/core/command/parser.js +65 -0
- package/dist/core/command/parser.js.map +1 -0
- package/dist/core/command/request.d.ts +61 -0
- package/dist/core/command/request.d.ts.map +1 -0
- package/dist/core/command/request.js +64 -0
- package/dist/core/command/request.js.map +1 -0
- package/dist/core/command/responses.d.ts +73 -0
- package/dist/core/command/responses.d.ts.map +1 -0
- package/dist/core/command/responses.js +97 -0
- package/dist/core/command/responses.js.map +1 -0
- package/dist/core/command-name.d.ts +349 -0
- package/dist/core/command-name.d.ts.map +1 -0
- package/dist/core/command-name.js +347 -0
- package/dist/core/command-name.js.map +1 -0
- package/dist/core/enums.d.ts +188 -0
- package/dist/core/enums.d.ts.map +1 -0
- package/dist/core/enums.js +172 -0
- package/dist/core/enums.js.map +1 -0
- package/dist/core/errorcode.d.ts +413 -0
- package/dist/core/errorcode.d.ts.map +1 -0
- package/dist/core/errorcode.js +410 -0
- package/dist/core/errorcode.js.map +1 -0
- package/dist/core/errors.d.ts +119 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +241 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +404 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +6 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/helpers.d.ts +42 -0
- package/dist/core/helpers.d.ts.map +1 -0
- package/dist/core/helpers.js +156 -0
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/index.d.ts +41 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +40 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/internal.d.ts +24 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +21 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/middleware.d.ts +14 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +18 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/notification-name.d.ts +160 -0
- package/dist/core/notification-name.d.ts.map +1 -0
- package/dist/core/notification-name.js +158 -0
- package/dist/core/notification-name.js.map +1 -0
- package/dist/core/notifications.d.ts +93 -0
- package/dist/core/notifications.d.ts.map +1 -0
- package/dist/core/notifications.js +301 -0
- package/dist/core/notifications.js.map +1 -0
- package/dist/core/permission-name.d.ts +1046 -0
- package/dist/core/permission-name.d.ts.map +1 -0
- package/dist/core/permission-name.js +1045 -0
- package/dist/core/permission-name.js.map +1 -0
- package/dist/core/permission.d.ts +31 -0
- package/dist/core/permission.d.ts.map +1 -0
- package/dist/core/permission.js +20 -0
- package/dist/core/permission.js.map +1 -0
- package/dist/core/property-name.d.ts +403 -0
- package/dist/core/property-name.d.ts.map +1 -0
- package/dist/core/property-name.js +405 -0
- package/dist/core/property-name.js.map +1 -0
- package/dist/core/reason.d.ts +39 -0
- package/dist/core/reason.d.ts.map +1 -0
- package/dist/core/reason.js +36 -0
- package/dist/core/reason.js.map +1 -0
- package/dist/core/reconnect.d.ts +59 -0
- package/dist/core/reconnect.d.ts.map +1 -0
- package/dist/core/reconnect.js +55 -0
- package/dist/core/reconnect.js.map +1 -0
- package/dist/core/types.d.ts +122 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +27 -0
- package/dist/core/types.js.map +1 -0
- package/dist/query/client.d.ts +244 -0
- package/dist/query/client.d.ts.map +1 -0
- package/dist/query/client.js +1122 -0
- package/dist/query/client.js.map +1 -0
- package/dist/query/errors.d.ts +61 -0
- package/dist/query/errors.d.ts.map +1 -0
- package/dist/query/errors.js +100 -0
- package/dist/query/errors.js.map +1 -0
- package/dist/query/index.d.ts +36 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +34 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/knownhosts.d.ts +61 -0
- package/dist/query/knownhosts.d.ts.map +1 -0
- package/dist/query/knownhosts.js +223 -0
- package/dist/query/knownhosts.js.map +1 -0
- package/dist/query/lines.d.ts +14 -0
- package/dist/query/lines.d.ts.map +1 -0
- package/dist/query/lines.js +29 -0
- package/dist/query/lines.js.map +1 -0
- package/dist/query/options.d.ts +206 -0
- package/dist/query/options.d.ts.map +1 -0
- package/dist/query/options.js +251 -0
- package/dist/query/options.js.map +1 -0
- package/dist/query/reconnect.d.ts +29 -0
- package/dist/query/reconnect.d.ts.map +1 -0
- package/dist/query/reconnect.js +87 -0
- package/dist/query/reconnect.js.map +1 -0
- package/dist/query/ssh.d.ts +385 -0
- package/dist/query/ssh.d.ts.map +1 -0
- package/dist/query/ssh.js +257 -0
- package/dist/query/ssh.js.map +1 -0
- package/dist/query/stream.d.ts +38 -0
- package/dist/query/stream.d.ts.map +1 -0
- package/dist/query/stream.js +70 -0
- package/dist/query/stream.js.map +1 -0
- package/dist/query/tcp.d.ts +38 -0
- package/dist/query/tcp.d.ts.map +1 -0
- package/dist/query/tcp.js +53 -0
- package/dist/query/tcp.js.map +1 -0
- package/dist/query/transport.d.ts +36 -0
- package/dist/query/transport.d.ts.map +1 -0
- package/dist/query/transport.js +2 -0
- package/dist/query/transport.js.map +1 -0
- package/dist/query/web.d.ts +78 -0
- package/dist/query/web.d.ts.map +1 -0
- package/dist/query/web.js +157 -0
- package/dist/query/web.js.map +1 -0
- package/dist/versions/index.d.ts +3094 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +9237 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +119 -4
- package/src/client/abort.ts +24 -0
- package/src/client/address.ts +74 -0
- package/src/client/api/avatars.ts +164 -0
- package/src/client/api/voice.ts +177 -0
- package/src/client/capabilities.ts +106 -0
- package/src/client/client.ts +1976 -0
- package/src/client/commands.ts +201 -0
- package/src/client/connection-info.ts +52 -0
- package/src/client/crypto/crypt-ops.ts +6 -0
- package/src/client/crypto/crypt.ts +275 -0
- package/src/client/crypto/eax.ts +152 -0
- package/src/client/crypto/identity.ts +484 -0
- package/src/client/crypto/index.ts +21 -0
- package/src/client/crypto/primitives.ts +141 -0
- package/src/client/diagnostics.ts +58 -0
- package/src/client/discovery/index.ts +1 -0
- package/src/client/discovery/resolver.ts +325 -0
- package/src/client/errors.ts +217 -0
- package/src/client/events.ts +12 -0
- package/src/client/handshake/crypt-handshake.ts +157 -0
- package/src/client/handshake/crypt-init2.ts +48 -0
- package/src/client/handshake/index.ts +3 -0
- package/src/client/handshake/license.ts +208 -0
- package/src/client/handshake.ts +150 -0
- package/src/client/helpers.ts +10 -0
- package/src/client/hooks.ts +30 -0
- package/src/client/index.ts +97 -0
- package/src/client/reconnect.ts +43 -0
- package/src/client/throttle.ts +92 -0
- package/src/client/trace.ts +237 -0
- package/src/client/transfer.ts +436 -0
- package/src/client/transport/generation-window.ts +108 -0
- package/src/client/transport/handler.ts +1021 -0
- package/src/client/transport/index.ts +14 -0
- package/src/client/transport/packet.ts +69 -0
- package/src/client/transport/quicklz.ts +209 -0
- package/src/client/transport/traffic.ts +116 -0
- package/src/client/types.ts +478 -0
- package/src/client/view.ts +372 -0
- package/src/core/api/avatars.ts +40 -0
- package/src/core/api/channels.ts +420 -0
- package/src/core/api/clients.ts +1098 -0
- package/src/core/api/command.ts +737 -0
- package/src/core/api/credentials.ts +335 -0
- package/src/core/api/files.ts +411 -0
- package/src/core/api/groups.ts +730 -0
- package/src/core/api/icons.ts +175 -0
- package/src/core/api/instance.ts +369 -0
- package/src/core/api/moderation.ts +632 -0
- package/src/core/api/parse.ts +139 -0
- package/src/core/api/server.ts +769 -0
- package/src/core/channel-tree.ts +398 -0
- package/src/core/command/command.ts +125 -0
- package/src/core/command/ids.ts +153 -0
- package/src/core/command/parser.ts +68 -0
- package/src/core/command/request.ts +119 -0
- package/src/core/command/responses.ts +152 -0
- package/src/core/command-name.ts +350 -0
- package/src/core/enums.ts +215 -0
- package/src/core/errorcode.ts +412 -0
- package/src/core/errors.ts +266 -0
- package/src/core/events.ts +431 -0
- package/src/core/helpers.ts +161 -0
- package/src/core/index.ts +153 -0
- package/src/core/internal.ts +24 -0
- package/src/core/middleware.ts +24 -0
- package/src/core/notification-name.ts +161 -0
- package/src/core/notifications.ts +404 -0
- package/src/core/permission-name.ts +1162 -0
- package/src/core/permission.ts +34 -0
- package/src/core/property-name.ts +411 -0
- package/src/core/reason.ts +38 -0
- package/src/core/reconnect.ts +98 -0
- package/src/core/types.ts +150 -0
- package/src/query/client.ts +1303 -0
- package/src/query/errors.ts +108 -0
- package/src/query/index.ts +66 -0
- package/src/query/knownhosts.ts +257 -0
- package/src/query/lines.ts +28 -0
- package/src/query/options.ts +452 -0
- package/src/query/reconnect.ts +84 -0
- package/src/query/ssh.ts +674 -0
- package/src/query/stream.ts +91 -0
- package/src/query/tcp.ts +85 -0
- package/src/query/transport.ts +35 -0
- package/src/query/web.ts +234 -0
- package/src/versions/index.ts +10774 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { createHash, createECDH, randomBytes } from "node:crypto";
|
|
2
|
+
import { HandshakeError, FakeSignatureMismatchError } from "../errors.js";
|
|
3
|
+
import { identityPrivateKey, importPublicKey } from "./identity.js";
|
|
4
|
+
import { EAX } from "./eax.js";
|
|
5
|
+
const FAKE_SIGNATURE_SIZE = 8;
|
|
6
|
+
const IV_ALPHA_SIZE = 10;
|
|
7
|
+
const INIT1_PACKET_TYPE = 8;
|
|
8
|
+
const PACKET_TYPE_MASK = 0x0f;
|
|
9
|
+
const INIT1_MAC = Buffer.from("TS3INIT1");
|
|
10
|
+
/**
|
|
11
|
+
* The most squarings the Init1 puzzle may ask for. TS3 3.13 and TS6 6.0 both
|
|
12
|
+
* ask for 10000; a level far beyond that is a server trying to pin the event
|
|
13
|
+
* loop, since the squarings run synchronously.
|
|
14
|
+
*/
|
|
15
|
+
export const MAX_RSA_CHALLENGE_LEVEL = 100_000;
|
|
16
|
+
/** Precomputed dummy key/nonce matching the TS3 client pre-crypto placeholder. */
|
|
17
|
+
const DUMMY_KEY = Buffer.from("c:\\windows\\syste");
|
|
18
|
+
const DUMMY_NONCE = Buffer.from("m\\firewall32.cpl");
|
|
19
|
+
/**
|
|
20
|
+
* A connection's encryption state. The session material — the IV the keys
|
|
21
|
+
* derive from — lives in private fields, so it shows in no `util.inspect()`
|
|
22
|
+
* or `JSON.stringify()` of anything holding a Crypt.
|
|
23
|
+
*/
|
|
24
|
+
export class Crypt {
|
|
25
|
+
identity;
|
|
26
|
+
#ivStruct = new Uint8Array(0);
|
|
27
|
+
#fakeSignature = new Uint8Array(FAKE_SIGNATURE_SIZE);
|
|
28
|
+
#alpha = new Uint8Array(0);
|
|
29
|
+
#cryptoInitComplete = false;
|
|
30
|
+
#cachedKeys = new Map();
|
|
31
|
+
constructor(identity) {
|
|
32
|
+
this.identity = identity;
|
|
33
|
+
}
|
|
34
|
+
/** Whether the session keys are set up; until then packets use the dummy key. */
|
|
35
|
+
get cryptoInitComplete() {
|
|
36
|
+
return this.#cryptoInitComplete;
|
|
37
|
+
}
|
|
38
|
+
/** The signature unencrypted packets carry: zeros until crypto init completes. */
|
|
39
|
+
get fakeSignature() {
|
|
40
|
+
return this.#fakeSignature;
|
|
41
|
+
}
|
|
42
|
+
/** The client's random contribution to the IV, sent in clientinitiv; empty before. */
|
|
43
|
+
get alpha() {
|
|
44
|
+
return this.#alpha;
|
|
45
|
+
}
|
|
46
|
+
/** Choose the client's random contribution to the IV, and return it. */
|
|
47
|
+
newAlpha() {
|
|
48
|
+
this.#alpha = new Uint8Array(randomBytes(IV_ALPHA_SIZE));
|
|
49
|
+
return this.#alpha;
|
|
50
|
+
}
|
|
51
|
+
solveRsaChallenge(data, offset, level) {
|
|
52
|
+
if (!Number.isInteger(level) || level < 0 || level > MAX_RSA_CHALLENGE_LEVEL) {
|
|
53
|
+
throw new HandshakeError(`RSA challenge level ${level} out of range`);
|
|
54
|
+
}
|
|
55
|
+
const xBytes = data.slice(offset, offset + 64);
|
|
56
|
+
const nBytes = data.slice(offset + 64, offset + 128);
|
|
57
|
+
let y = bytesToBigInt(xBytes);
|
|
58
|
+
const n = bytesToBigInt(nBytes);
|
|
59
|
+
if (n === 0n)
|
|
60
|
+
throw new HandshakeError("RSA challenge modulus is zero");
|
|
61
|
+
for (let i = 0; i < level; i++) {
|
|
62
|
+
y = (y * y) % n;
|
|
63
|
+
}
|
|
64
|
+
return bigIntToBytes(y, 64);
|
|
65
|
+
}
|
|
66
|
+
initCrypto(alpha, beta, omega) {
|
|
67
|
+
const alphaBytes = Buffer.from(alpha, "base64");
|
|
68
|
+
const betaBytes = Buffer.from(beta, "base64");
|
|
69
|
+
const omegaBytes = Buffer.from(omega, "base64");
|
|
70
|
+
let sharedSecret;
|
|
71
|
+
try {
|
|
72
|
+
sharedSecret = this.#getSharedSecret(importPublicKey(omegaBytes));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw new HandshakeError("the server's public key is invalid", { cause: error });
|
|
76
|
+
}
|
|
77
|
+
this.setSharedSecret(alphaBytes, betaBytes, sharedSecret);
|
|
78
|
+
}
|
|
79
|
+
setSharedSecret(alpha, beta, sharedKey) {
|
|
80
|
+
this.#ivStruct = new Uint8Array(IV_ALPHA_SIZE + beta.length);
|
|
81
|
+
for (let i = 0; i < IV_ALPHA_SIZE; i++) {
|
|
82
|
+
const a = sharedKey[i];
|
|
83
|
+
const b = alpha[i];
|
|
84
|
+
this.#ivStruct[i] = ((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;
|
|
85
|
+
}
|
|
86
|
+
for (let i = 0; i < beta.length; i++) {
|
|
87
|
+
const a = sharedKey[IV_ALPHA_SIZE + i];
|
|
88
|
+
const b = beta[i];
|
|
89
|
+
this.#ivStruct[IV_ALPHA_SIZE + i] =
|
|
90
|
+
((a !== undefined ? a : 0) ^ (b !== undefined ? b : 0)) & 0xff;
|
|
91
|
+
}
|
|
92
|
+
// Keys derive from the IV: any cached before it changed belong to another
|
|
93
|
+
// IV, the empty one before crypto init in particular, which is public.
|
|
94
|
+
this.#cachedKeys.clear();
|
|
95
|
+
const digest = createHash("sha1").update(this.#ivStruct).digest();
|
|
96
|
+
this.#fakeSignature = new Uint8Array(digest.buffer, digest.byteOffset, FAKE_SIGNATURE_SIZE);
|
|
97
|
+
this.#cryptoInitComplete = true;
|
|
98
|
+
}
|
|
99
|
+
getKeyNonce(fromServer, packetID, generationID, packetType, dummy) {
|
|
100
|
+
if (dummy) {
|
|
101
|
+
return [Uint8Array.from(DUMMY_KEY), Uint8Array.from(DUMMY_NONCE)];
|
|
102
|
+
}
|
|
103
|
+
// Before crypto init there is no IV, and a key derived from the empty one
|
|
104
|
+
// is a key anyone can compute.
|
|
105
|
+
if (!this.#cryptoInitComplete) {
|
|
106
|
+
throw new HandshakeError("no session key before crypto init completes");
|
|
107
|
+
}
|
|
108
|
+
const cacheKey = makeCacheKey(fromServer, packetType, generationID);
|
|
109
|
+
let kn = this.#cachedKeys.get(cacheKey);
|
|
110
|
+
if (kn === undefined) {
|
|
111
|
+
const tmpToHash = new Uint8Array(6 + this.#ivStruct.length);
|
|
112
|
+
tmpToHash[0] = fromServer ? 0x30 : 0x31;
|
|
113
|
+
tmpToHash[1] = packetType & PACKET_TYPE_MASK;
|
|
114
|
+
new DataView(tmpToHash.buffer).setUint32(2, generationID, false);
|
|
115
|
+
tmpToHash.set(this.#ivStruct, 6);
|
|
116
|
+
const hash = createHash("sha256").update(tmpToHash).digest();
|
|
117
|
+
kn = {
|
|
118
|
+
key: Uint8Array.from(hash.subarray(0, 16)),
|
|
119
|
+
nonce: Uint8Array.from(hash.subarray(16, 32)),
|
|
120
|
+
gen: generationID,
|
|
121
|
+
};
|
|
122
|
+
this.#cachedKeys.set(cacheKey, kn);
|
|
123
|
+
}
|
|
124
|
+
const key = Uint8Array.from(kn.key);
|
|
125
|
+
key[0] = (key[0] !== undefined ? key[0] : 0) ^ ((packetID >> 8) & 0xff);
|
|
126
|
+
key[1] = (key[1] !== undefined ? key[1] : 0) ^ (packetID & 0xff);
|
|
127
|
+
return [key, kn.nonce];
|
|
128
|
+
}
|
|
129
|
+
encrypt(packetType, packetID, generationID, header, plaintext, dummy, unencrypted) {
|
|
130
|
+
if (packetType === INIT1_PACKET_TYPE) {
|
|
131
|
+
return [plaintext, INIT1_MAC];
|
|
132
|
+
}
|
|
133
|
+
if (unencrypted) {
|
|
134
|
+
return [plaintext, this.#fakeSignature];
|
|
135
|
+
}
|
|
136
|
+
const [key, nonce] = this.getKeyNonce(false, packetID, generationID, packetType, dummy);
|
|
137
|
+
const eax = new EAX(key);
|
|
138
|
+
return eax.encrypt(nonce, header, plaintext);
|
|
139
|
+
}
|
|
140
|
+
decrypt(packetType, packetID, generationID, header, ciphertext, tag, dummy, unencrypted) {
|
|
141
|
+
if (packetType === INIT1_PACKET_TYPE) {
|
|
142
|
+
return ciphertext;
|
|
143
|
+
}
|
|
144
|
+
if (unencrypted) {
|
|
145
|
+
const fsSub = tag.slice(0, FAKE_SIGNATURE_SIZE);
|
|
146
|
+
if (!Buffer.from(fsSub).equals(Buffer.from(this.#fakeSignature))) {
|
|
147
|
+
throw new FakeSignatureMismatchError();
|
|
148
|
+
}
|
|
149
|
+
return ciphertext;
|
|
150
|
+
}
|
|
151
|
+
const [key, nonce] = this.getKeyNonce(true, packetID, generationID, packetType, dummy);
|
|
152
|
+
const eax = new EAX(key);
|
|
153
|
+
return eax.decrypt(nonce, header, ciphertext, tag);
|
|
154
|
+
}
|
|
155
|
+
#getSharedSecret(serverPubKey) {
|
|
156
|
+
const privJwk = identityPrivateKey(this.identity).export({ format: "jwk" });
|
|
157
|
+
const pubJwk = serverPubKey.export({ format: "jwk" });
|
|
158
|
+
const ecdh = createECDH("prime256v1");
|
|
159
|
+
const dBytes = Buffer.from(privJwk.d, "base64url");
|
|
160
|
+
ecdh.setPrivateKey(dBytes);
|
|
161
|
+
const xBytes = base64UrlToBytes(pubJwk.x, 32);
|
|
162
|
+
const yBytes = base64UrlToBytes(pubJwk.y, 32);
|
|
163
|
+
const uncompressed = Buffer.alloc(65);
|
|
164
|
+
uncompressed[0] = 0x04;
|
|
165
|
+
xBytes.copy(uncompressed, 1);
|
|
166
|
+
yBytes.copy(uncompressed, 33);
|
|
167
|
+
const rawSecret = ecdh.computeSecret(uncompressed);
|
|
168
|
+
return createHash("sha1").update(rawSecret).digest();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---- Helpers ----------------------------------------------------------------
|
|
172
|
+
function makeCacheKey(fromServer, packetType, generationID) {
|
|
173
|
+
let key = 0n;
|
|
174
|
+
if (fromServer)
|
|
175
|
+
key |= 1n << 40n;
|
|
176
|
+
key |= BigInt(packetType & PACKET_TYPE_MASK) << 32n;
|
|
177
|
+
key |= BigInt(generationID);
|
|
178
|
+
return key;
|
|
179
|
+
}
|
|
180
|
+
function bytesToBigInt(bytes) {
|
|
181
|
+
let result = 0n;
|
|
182
|
+
for (const b of bytes)
|
|
183
|
+
result = (result << 8n) | BigInt(b);
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
function bigIntToBytes(value, size) {
|
|
187
|
+
const result = new Uint8Array(size);
|
|
188
|
+
let v = value;
|
|
189
|
+
for (let i = size - 1; i >= 0; i--) {
|
|
190
|
+
result[i] = Number(v & 0xffn);
|
|
191
|
+
v >>= 8n;
|
|
192
|
+
}
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
function base64UrlToBytes(b64url, size) {
|
|
196
|
+
const buf = Buffer.from(b64url, "base64url");
|
|
197
|
+
if (buf.length === size)
|
|
198
|
+
return buf;
|
|
199
|
+
const padded = Buffer.alloc(size);
|
|
200
|
+
buf.copy(padded, size - buf.length);
|
|
201
|
+
return padded;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=crypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypt.js","sourceRoot":"","sources":["../../../src/client/crypto/crypt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).
|
|
3
|
+
* Uses AES-CMAC for authentication and AES-CTR for encryption.
|
|
4
|
+
*/
|
|
5
|
+
export declare class EAX {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(key: Uint8Array);
|
|
8
|
+
encrypt(nonce: Uint8Array, header: Uint8Array, plaintext: Uint8Array): [ciphertext: Uint8Array, tag: Uint8Array];
|
|
9
|
+
decrypt(nonce: Uint8Array, header: Uint8Array, ciphertext: Uint8Array, tag: Uint8Array): Uint8Array;
|
|
10
|
+
}
|
|
11
|
+
export declare function aesCmac(key: Uint8Array, message: Uint8Array): Uint8Array;
|
|
12
|
+
//# sourceMappingURL=eax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eax.d.ts","sourceRoot":"","sources":["../../../src/client/crypto/eax.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,qBAAa,GAAG;;IAGd,YAAY,GAAG,EAAE,UAAU,EAG1B;IAED,OAAO,CACL,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,UAAU,GACpB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAc3C;IAED,OAAO,CACL,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,UAAU,GACd,UAAU,CAeZ;CAcF;AAoDD,wBAAgB,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,CA2BxE"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createCipheriv, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { EAXTagMismatchError } from "../errors.js";
|
|
3
|
+
const EAX_TAG_SIZE = 8;
|
|
4
|
+
const EAX_BLOCK_SIZE = 16;
|
|
5
|
+
/**
|
|
6
|
+
* AES-EAX AEAD implementation for TS3 (64-bit tag, AES-128).
|
|
7
|
+
* Uses AES-CMAC for authentication and AES-CTR for encryption.
|
|
8
|
+
*/
|
|
9
|
+
export class EAX {
|
|
10
|
+
#key;
|
|
11
|
+
constructor(key) {
|
|
12
|
+
if (key.length !== 16)
|
|
13
|
+
throw new Error("EAX requires a 16-byte key");
|
|
14
|
+
this.#key = key;
|
|
15
|
+
}
|
|
16
|
+
encrypt(nonce, header, plaintext) {
|
|
17
|
+
const nStar = this.#cmac(0, nonce);
|
|
18
|
+
const hStar = this.#cmac(1, header);
|
|
19
|
+
const ciphertext = aesCtr(this.#key, nStar, plaintext);
|
|
20
|
+
const cStar = this.#cmac(2, ciphertext);
|
|
21
|
+
const tag = new Uint8Array(EAX_TAG_SIZE);
|
|
22
|
+
for (let i = 0; i < EAX_TAG_SIZE; i++) {
|
|
23
|
+
tag[i] = nStar[i] ^ hStar[i] ^ cStar[i];
|
|
24
|
+
}
|
|
25
|
+
return [ciphertext, tag];
|
|
26
|
+
}
|
|
27
|
+
decrypt(nonce, header, ciphertext, tag) {
|
|
28
|
+
const nStar = this.#cmac(0, nonce);
|
|
29
|
+
const hStar = this.#cmac(1, header);
|
|
30
|
+
const cStar = this.#cmac(2, ciphertext);
|
|
31
|
+
const expected = new Uint8Array(EAX_TAG_SIZE);
|
|
32
|
+
for (let i = 0; i < EAX_TAG_SIZE; i++) {
|
|
33
|
+
expected[i] = nStar[i] ^ hStar[i] ^ cStar[i];
|
|
34
|
+
}
|
|
35
|
+
if (!timingSafeEqual(Buffer.from(expected), Buffer.from(tag.slice(0, EAX_TAG_SIZE)))) {
|
|
36
|
+
throw new EAXTagMismatchError();
|
|
37
|
+
}
|
|
38
|
+
return aesCtr(this.#key, nStar, ciphertext);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* AES-CMAC per RFC 4493:
|
|
42
|
+
* input = [0…0 tag] ++ data (one block prefix)
|
|
43
|
+
*/
|
|
44
|
+
#cmac(tagByte, data) {
|
|
45
|
+
const input = new Uint8Array(EAX_BLOCK_SIZE + data.length);
|
|
46
|
+
// first block: zeros then tag byte at the last position
|
|
47
|
+
input[EAX_BLOCK_SIZE - 1] = tagByte;
|
|
48
|
+
input.set(data, EAX_BLOCK_SIZE);
|
|
49
|
+
return aesCmac(this.#key, input);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ---- AES-CTR ----------------------------------------------------------------
|
|
53
|
+
function aesCtr(key, iv, data) {
|
|
54
|
+
const cipher = createCipheriv("aes-128-ctr", Buffer.from(key), Buffer.from(iv));
|
|
55
|
+
return Buffer.concat([cipher.update(Buffer.from(data)), cipher.final()]);
|
|
56
|
+
}
|
|
57
|
+
// ---- AES-CMAC (RFC 4493) ----------------------------------------------------
|
|
58
|
+
function aesEcb(key, block) {
|
|
59
|
+
// Node.js does not expose ECB directly; simulate via CTR with zero IV and
|
|
60
|
+
// a zero-input (CTR of 0-block XOR with input = ECB)
|
|
61
|
+
const cipher = createCipheriv("aes-128-ecb", Buffer.from(key), null);
|
|
62
|
+
cipher.setAutoPadding(false);
|
|
63
|
+
return Buffer.concat([cipher.update(Buffer.from(block)), cipher.final()]);
|
|
64
|
+
}
|
|
65
|
+
function xorBlock(a, b) {
|
|
66
|
+
const out = new Uint8Array(EAX_BLOCK_SIZE);
|
|
67
|
+
for (let i = 0; i < EAX_BLOCK_SIZE; i++)
|
|
68
|
+
out[i] = a[i] ^ b[i];
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
function shiftLeft1(b) {
|
|
72
|
+
const out = new Uint8Array(EAX_BLOCK_SIZE);
|
|
73
|
+
let carry = 0;
|
|
74
|
+
for (let i = EAX_BLOCK_SIZE - 1; i >= 0; i--) {
|
|
75
|
+
const shifted = ((b[i] << 1) | carry) & 0xff;
|
|
76
|
+
carry = b[i] >> 7;
|
|
77
|
+
out[i] = shifted;
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
const RB = new Uint8Array(EAX_BLOCK_SIZE);
|
|
82
|
+
RB[EAX_BLOCK_SIZE - 1] = 0x87;
|
|
83
|
+
function generateSubkeys(key) {
|
|
84
|
+
const zero = new Uint8Array(EAX_BLOCK_SIZE);
|
|
85
|
+
const L = aesEcb(key, zero);
|
|
86
|
+
let K1 = shiftLeft1(L);
|
|
87
|
+
if ((L[0] & 0x80) !== 0)
|
|
88
|
+
K1 = xorBlock(K1, RB);
|
|
89
|
+
let K2 = shiftLeft1(K1);
|
|
90
|
+
if ((K1[0] & 0x80) !== 0)
|
|
91
|
+
K2 = xorBlock(K2, RB);
|
|
92
|
+
return [K1, K2];
|
|
93
|
+
}
|
|
94
|
+
export function aesCmac(key, message) {
|
|
95
|
+
const [K1, K2] = generateSubkeys(key);
|
|
96
|
+
const n = Math.max(1, Math.ceil(message.length / EAX_BLOCK_SIZE));
|
|
97
|
+
const lastBlockComplete = message.length > 0 && message.length % EAX_BLOCK_SIZE === 0;
|
|
98
|
+
let X = new Uint8Array(EAX_BLOCK_SIZE);
|
|
99
|
+
for (let i = 0; i < n - 1; i++) {
|
|
100
|
+
const block = message.slice(i * EAX_BLOCK_SIZE, (i + 1) * EAX_BLOCK_SIZE);
|
|
101
|
+
X = Uint8Array.from(aesEcb(key, xorBlock(X, block)));
|
|
102
|
+
}
|
|
103
|
+
const lastBlock = new Uint8Array(EAX_BLOCK_SIZE);
|
|
104
|
+
const lastStart = (n - 1) * EAX_BLOCK_SIZE;
|
|
105
|
+
const lastSlice = message.slice(lastStart);
|
|
106
|
+
lastBlock.set(lastSlice);
|
|
107
|
+
let Mn;
|
|
108
|
+
if (lastBlockComplete) {
|
|
109
|
+
Mn = xorBlock(lastBlock, K1);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
if (lastSlice.length < EAX_BLOCK_SIZE)
|
|
113
|
+
lastBlock[lastSlice.length] = 0x80;
|
|
114
|
+
Mn = xorBlock(lastBlock, K2);
|
|
115
|
+
}
|
|
116
|
+
return Uint8Array.from(aesEcb(key, xorBlock(X, Mn)));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=eax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eax.js","sourceRoot":"","sources":["../../../src/client/crypto/eax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type KeyObject } from "node:crypto";
|
|
2
|
+
import { type UID } from "@honeybbq/teamspeak";
|
|
3
|
+
/**
|
|
4
|
+
* A TeamSpeak client identity: a P-256 key pair plus a counter, the offset,
|
|
5
|
+
* whose hash with the public key sets the identity's security level.
|
|
6
|
+
*
|
|
7
|
+
* Immutable: raising the level returns a new identity. Opaque: the private
|
|
8
|
+
* key is never exposed, and `toString()`, `toJSON()` and `util.inspect()`
|
|
9
|
+
* describe the identity without it, so an identity that reaches a log or an
|
|
10
|
+
* error message does not leak; `export()` is the one way to get the secret
|
|
11
|
+
* form, for storing it. Make one with `generateIdentity()` or
|
|
12
|
+
* `parseIdentity()`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class Identity {
|
|
15
|
+
#private;
|
|
16
|
+
private constructor();
|
|
17
|
+
/** The counter whose hash with the public key sets the security level. */
|
|
18
|
+
get offset(): bigint;
|
|
19
|
+
/** The public key in TeamSpeak's encoding: base64 of its DER form. */
|
|
20
|
+
publicKey(): string;
|
|
21
|
+
/**
|
|
22
|
+
* The identity's unique identifier, hashed with `algorithm`: SHA-1 for a
|
|
23
|
+
* TeamSpeak 3 server, SHA-256 for TeamSpeak 6. A connected client's `uid`
|
|
24
|
+
* already uses the one its server does.
|
|
25
|
+
*/
|
|
26
|
+
uid(algorithm: UIDAlgorithm): UID;
|
|
27
|
+
/**
|
|
28
|
+
* The identity in the form `parseIdentity()` reads, private key included.
|
|
29
|
+
* Store it as you would a password.
|
|
30
|
+
*/
|
|
31
|
+
export(): string;
|
|
32
|
+
/** Describes the identity, by its SHA-1 unique identifier, without its private key. */
|
|
33
|
+
toString(): string;
|
|
34
|
+
/** The same as `toString()`, so serialising an identity cannot leak its key. */
|
|
35
|
+
toJSON(): string;
|
|
36
|
+
/** The security level: trailing zero bits in SHA-1 of the public key and offset. */
|
|
37
|
+
securityLevel(): number;
|
|
38
|
+
/**
|
|
39
|
+
* The same key at an offset whose security level reaches `targetLevel`, as
|
|
40
|
+
* a new identity; this one is unchanged, and returned as it is when it
|
|
41
|
+
* already reaches the level.
|
|
42
|
+
*
|
|
43
|
+
* Each level doubles the expected work, so a high level can take a long
|
|
44
|
+
* time; `signal` bounds it, and the event loop keeps running meanwhile. A
|
|
45
|
+
* level above 160, the width of SHA-1, can never be reached and is refused
|
|
46
|
+
* with a RangeError.
|
|
47
|
+
*/
|
|
48
|
+
upgradeToLevel(targetLevel: number, options?: {
|
|
49
|
+
readonly signal?: AbortSignal | undefined;
|
|
50
|
+
}): Promise<Identity>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Read an identity from the form `Identity.export()` writes: the private key
|
|
54
|
+
* as canonical base64 of at most 32 bytes, a colon, and the offset as a
|
|
55
|
+
* decimal unsigned 64-bit integer. Anything else throws an
|
|
56
|
+
* InvalidIdentityError, with the underlying failure as its cause.
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseIdentity(s: string): Identity;
|
|
59
|
+
/**
|
|
60
|
+
* Create an identity at the given security level, at most 160. Each level
|
|
61
|
+
* doubles the expected work; `signal` bounds it, and the event loop keeps
|
|
62
|
+
* running meanwhile.
|
|
63
|
+
*/
|
|
64
|
+
export declare function generateIdentity(targetLevel: number, options?: {
|
|
65
|
+
readonly signal?: AbortSignal | undefined;
|
|
66
|
+
}): Promise<Identity>;
|
|
67
|
+
/**
|
|
68
|
+
* Create an identity at the given security level, at most 160, blocking until
|
|
69
|
+
* done. Fine for a low level; a high one can block the event loop for minutes,
|
|
70
|
+
* so prefer `generateIdentity()` there.
|
|
71
|
+
*/
|
|
72
|
+
export declare function generateIdentitySync(targetLevel: number): Identity;
|
|
73
|
+
/**
|
|
74
|
+
* The hash a server uses for `client_unique_identifier`, keyed by the server's
|
|
75
|
+
* major version.
|
|
76
|
+
*
|
|
77
|
+
* TeamSpeak 3 hashes the canonical public key with SHA-1 (20 bytes); TeamSpeak
|
|
78
|
+
* 6 switched to SHA-256 (32 bytes). The algorithm is not negotiable on the
|
|
79
|
+
* wire, so a client that guesses wrong computes a UID that matches nothing the
|
|
80
|
+
* server ever sends — self-identification by UID silently fails.
|
|
81
|
+
*
|
|
82
|
+
* May gain members in a minor release, should a server generation change the
|
|
83
|
+
* hash again: a `switch` over it needs a default case.
|
|
84
|
+
*/
|
|
85
|
+
export type UIDAlgorithm = "sha1" | "sha256";
|
|
86
|
+
/** Pick the UID hash from a `virtualserver_version` string, e.g. "6.0.0-beta13.1". */
|
|
87
|
+
export declare function uidAlgorithmForVersion(version: string): UIDAlgorithm;
|
|
88
|
+
/**
|
|
89
|
+
* The unique identifier of a public key in TeamSpeak's encoding, hashed with
|
|
90
|
+
* `algorithm`: SHA-1 for a TeamSpeak 3 server, SHA-256 for TeamSpeak 6.
|
|
91
|
+
*/
|
|
92
|
+
export declare function uidFromPublicKey(publicKey: string, algorithm: UIDAlgorithm): UID;
|
|
93
|
+
export declare function hash512(data: Uint8Array): Uint8Array;
|
|
94
|
+
/** Import a TS3 public key (canonical or legacy ASN.1 DER) and return the
|
|
95
|
+
* uncompressed 65-byte point [0x04 || x || y]. */
|
|
96
|
+
export declare function importPublicKey(data: Uint8Array): KeyObject;
|
|
97
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/client/crypto/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,SAAS,EACf,MAAM,aAAa,CAAC;AAErB,OAAO,EAAS,KAAK,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAYtD;;;;;;;;;;GAUG;AACH,qBAAa,QAAQ;;IAUnB,OAAO,eAGN;IAED,0EAA0E;IAC1E,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,sEAAsE;IACtE,SAAS,IAAI,MAAM,CAUlB;IAED;;;;OAIG;IACH,GAAG,CAAC,SAAS,EAAE,YAAY,GAAG,GAAG,CAEhC;IAED;;;OAGG;IACH,MAAM,IAAI,MAAM,CAKf;IAED,uFAAuF;IACvF,QAAQ,IAAI,MAAM,CAEjB;IAED,gFAAgF;IAChF,MAAM,IAAI,MAAM,CAEf;IAED,oFAAoF;IACpF,aAAa,IAAI,MAAM,CAEtB;IAED;;;;;;;;;OASG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;KAAO,GAC1D,OAAO,CAAC,QAAQ,CAAC,CAgBnB;CACF;AAqCD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ,CA0CjD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CAAO,GAC1D,OAAO,CAAC,QAAQ,CAAC,CAGnB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,QAAQ,CAOlE;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7C,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAGpE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,GAAG,GAAG,CAEhF;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEpD;AA+BD;mDACmD;AACnD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAS3D"}
|