@corewire/core 0.0.0 → 1.0.0-next.1
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 +28 -1
- package/dist/chunk-wE0WeVzl.mjs +22 -0
- package/dist/crypto-CXSIS6si.mjs +3093 -0
- package/dist/crypto.d.mts +111 -0
- package/dist/crypto.mjs +3 -0
- package/dist/discovery.d.mts +110 -0
- package/dist/discovery.mjs +763 -0
- package/dist/encoding-BaLbwFQ0.mjs +1663 -0
- package/dist/encoding.d.mts +411 -0
- package/dist/encoding.mjs +3 -0
- package/dist/errors-DVv1n4fL.mjs +125 -0
- package/dist/index-BJKNwUmq.d.mts +125 -0
- package/dist/index.d.mts +82 -0
- package/dist/index.mjs +5 -0
- package/dist/pairing.d.mts +169 -0
- package/dist/pairing.mjs +2487 -0
- package/dist/reporter-DfM6vPT0.mjs +223 -0
- package/dist/reporter-Dn7n2TXN.d.mts +112 -0
- package/dist/transport-C4BMdD2J.mjs +270 -0
- package/dist/transport.d.mts +2 -0
- package/dist/transport.mjs +3 -0
- package/dist/types-qzabRJJ9.d.mts +5 -0
- package/dist/utils-DY5OKUuy.mjs +8 -0
- package/package.json +80 -18
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { a as ReporterEntry, c as TrafficDirection, d as TrafficSink, f as reporter, i as Reporter, l as TrafficEntry, n as LogSink, o as ReporterSink, r as Logger, s as ReporterSinkOptions, t as DebugGroup, u as TrafficProtocol } from "./reporter-Dn7n2TXN.mjs";
|
|
2
|
+
import { t as EventMap } from "./types-qzabRJJ9.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/errors.d.ts
|
|
5
|
+
/** Base class of the CoreWire errors, so one `instanceof` check catches all of them. */
|
|
6
|
+
declare class AppleProtocolError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/** Thrown when a TCP connection fails to open or breaks. */
|
|
10
|
+
declare class ConnectionError extends AppleProtocolError {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
/** Thrown when a TCP connection attempt exceeds the configured socket timeout. */
|
|
14
|
+
declare class ConnectionTimeoutError extends ConnectionError {
|
|
15
|
+
constructor(message?: string);
|
|
16
|
+
}
|
|
17
|
+
/** Thrown when a connection or session closes before an operation finishes, or when an operation runs on a closed one. */
|
|
18
|
+
declare class ConnectionClosedError extends ConnectionError {
|
|
19
|
+
constructor(message?: string);
|
|
20
|
+
}
|
|
21
|
+
/** Thrown when a HAP pair-setup or pair-verify fails. */
|
|
22
|
+
declare class PairingError extends AppleProtocolError {
|
|
23
|
+
constructor(message: string);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Thrown when the accessory's identity verification fails, such as an invalid
|
|
27
|
+
* Ed25519 signature or mismatched accessory identifier during pair-verify.
|
|
28
|
+
*/
|
|
29
|
+
declare class AuthenticationError extends PairingError {
|
|
30
|
+
constructor(message: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Thrown when stored credentials are invalid, missing, or incompatible
|
|
34
|
+
* with the accessory (e.g. after a factory reset).
|
|
35
|
+
*/
|
|
36
|
+
declare class CredentialsError extends PairingError {
|
|
37
|
+
constructor(message: string);
|
|
38
|
+
}
|
|
39
|
+
/** Thrown when a protocol command fails to execute on the target device. */
|
|
40
|
+
declare class CommandError extends AppleProtocolError {
|
|
41
|
+
constructor(message: string);
|
|
42
|
+
}
|
|
43
|
+
/** Thrown when a protocol setup step fails (e.g. an RTSP SETUP). */
|
|
44
|
+
declare class SetupError extends AppleProtocolError {
|
|
45
|
+
constructor(message: string);
|
|
46
|
+
}
|
|
47
|
+
/** Thrown when mDNS device discovery fails or a device cannot be found after retries. */
|
|
48
|
+
declare class DiscoveryError extends AppleProtocolError {
|
|
49
|
+
constructor(message: string);
|
|
50
|
+
}
|
|
51
|
+
/** Thrown when encrypting or decrypting a message fails. */
|
|
52
|
+
declare class EncryptionError extends AppleProtocolError {
|
|
53
|
+
constructor(message: string);
|
|
54
|
+
}
|
|
55
|
+
/** Thrown when a response from the accessory is malformed or has an unexpected format. */
|
|
56
|
+
declare class InvalidResponseError extends AppleProtocolError {
|
|
57
|
+
constructor(message: string);
|
|
58
|
+
}
|
|
59
|
+
/** Thrown when a protocol operation exceeds its expected time limit. */
|
|
60
|
+
declare class TimeoutError extends AppleProtocolError {
|
|
61
|
+
constructor(message: string);
|
|
62
|
+
}
|
|
63
|
+
/** Thrown when a media playback operation fails on the target device. */
|
|
64
|
+
declare class PlaybackError extends AppleProtocolError {
|
|
65
|
+
constructor(message: string);
|
|
66
|
+
}
|
|
67
|
+
/** Thrown when the authentication tag of a ChaCha20-Poly1305 message does not match, because the ciphertext changed or the key or nonce is wrong. */
|
|
68
|
+
declare class DecryptionError extends EncryptionError {
|
|
69
|
+
constructor(message?: string);
|
|
70
|
+
}
|
|
71
|
+
/** Thrown when the accessory answers a pairing message with a TLV8 error or back-off. */
|
|
72
|
+
declare class TLV8PairingError extends PairingError {
|
|
73
|
+
/** The TLV8 error code of the accessory; undefined when it sent none. */
|
|
74
|
+
readonly code: number | undefined;
|
|
75
|
+
constructor(message: string, code?: number);
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/utils.d.ts
|
|
79
|
+
/** Resolves after `ms` milliseconds. */
|
|
80
|
+
declare function waitFor(ms: number): Promise<void>;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { AppleProtocolError, AuthenticationError, CommandError, ConnectionClosedError, ConnectionError, ConnectionTimeoutError, CredentialsError, type DebugGroup, DecryptionError, DiscoveryError, EncryptionError, type EventMap, InvalidResponseError, type LogSink, Logger, PairingError, PlaybackError, type Reporter, type ReporterEntry, type ReporterSink, type ReporterSinkOptions, SetupError, TLV8PairingError, TimeoutError, type TrafficDirection, type TrafficEntry, type TrafficProtocol, type TrafficSink, reporter, waitFor };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { a as ConnectionError, c as DecryptionError, d as InvalidResponseError, f as PairingError, g as TimeoutError, h as TLV8PairingError, i as ConnectionClosedError, l as DiscoveryError, m as SetupError, n as AuthenticationError, o as ConnectionTimeoutError, p as PlaybackError, r as CommandError, s as CredentialsError, t as AppleProtocolError, u as EncryptionError } from "./errors-DVv1n4fL.mjs";
|
|
2
|
+
import { n as reporter, t as Logger } from "./reporter-DfM6vPT0.mjs";
|
|
3
|
+
import { t as waitFor } from "./utils-DY5OKUuy.mjs";
|
|
4
|
+
|
|
5
|
+
export { AppleProtocolError, AuthenticationError, CommandError, ConnectionClosedError, ConnectionError, ConnectionTimeoutError, CredentialsError, DecryptionError, DiscoveryError, EncryptionError, InvalidResponseError, Logger, PairingError, PlaybackError, SetupError, TLV8PairingError, TimeoutError, reporter, waitFor };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { c as Context } from "./index-BJKNwUmq.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/pairing/cipher.d.ts
|
|
4
|
+
/** The HAP channel keys, named from the controller's side: we decrypt with `Control-Read-Encryption-Key`. */
|
|
5
|
+
declare function deriveControlKeys(sharedSecret: Buffer): {
|
|
6
|
+
accessoryToControllerKey: Buffer;
|
|
7
|
+
controllerToAccessoryKey: Buffer;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/pairing/types.d.ts
|
|
11
|
+
/** The HAP pairing message a controller sends: M1, M3 or M5. */
|
|
12
|
+
type PairingStep = "m1" | "m3" | "m5";
|
|
13
|
+
/**
|
|
14
|
+
* Carries one pairing message to the accessory and resolves with its reply. Pairing only knows
|
|
15
|
+
* TLV8; the protocol knows the frame (an HTTP body, an OPack frame). Some protocols frame the
|
|
16
|
+
* first message differently, hence the step.
|
|
17
|
+
*/
|
|
18
|
+
type PairingTransport = (payload: Buffer, step: PairingStep) => Promise<Buffer>;
|
|
19
|
+
/** Long-term credentials from a PIN pair-setup, reused by every later pair-verify. */
|
|
20
|
+
type AccessoryCredentials = {
|
|
21
|
+
readonly accessoryIdentifier: string;
|
|
22
|
+
readonly accessoryLongTermPublicKey: Buffer; /** This controller's pairing identifier (an uppercase UUID). */
|
|
23
|
+
readonly pairingId: Buffer; /** This controller's Ed25519 key pair. */
|
|
24
|
+
readonly publicKey: Buffer;
|
|
25
|
+
readonly secretKey: Buffer;
|
|
26
|
+
};
|
|
27
|
+
/** Session keys from a transient pair-setup or a pair-verify. */
|
|
28
|
+
type AccessoryKeys = {
|
|
29
|
+
readonly pairingId: Buffer; /** Root key for the HKDF derivation of the channel keys. */
|
|
30
|
+
readonly sharedSecret: Buffer; /** Empty after a bare pair-verify; the protocol derives its own channel keys from {@link sharedSecret}. */
|
|
31
|
+
readonly accessoryToControllerKey: Buffer;
|
|
32
|
+
readonly controllerToAccessoryKey: Buffer;
|
|
33
|
+
};
|
|
34
|
+
/** The persistent identity an accessory presents. Persist it, or paired controllers lose their pairing. */
|
|
35
|
+
type AccessoryIdentity = {
|
|
36
|
+
/** A MAC-like pairing identifier, e.g. "AA:BB:CC:DD:EE:FF". */readonly identifier: string;
|
|
37
|
+
readonly publicKey: Buffer;
|
|
38
|
+
readonly secretKey: Buffer;
|
|
39
|
+
};
|
|
40
|
+
/** A controller that completed pair-setup with the accessory. */
|
|
41
|
+
type PairedController = {
|
|
42
|
+
readonly identifier: string;
|
|
43
|
+
readonly longTermPublicKey: Buffer;
|
|
44
|
+
};
|
|
45
|
+
/** Looks up a paired controller's long-term public key; undefined rejects the pair-verify. */
|
|
46
|
+
type ControllerResolver = (pairingId: string) => Buffer | undefined;
|
|
47
|
+
/** Options shared by the controller and accessory sides. */
|
|
48
|
+
type PairingOptions = {
|
|
49
|
+
/** AES-128-CTR instead of ChaCha20-Poly1305 for the encrypted sub-TLVs, for legacy devices. */readonly useAes?: boolean;
|
|
50
|
+
};
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/pairing/client.d.ts
|
|
53
|
+
/**
|
|
54
|
+
* Runs HAP pair-setup as the controller, with SRP-6a followed by an Ed25519 identity exchange.
|
|
55
|
+
*
|
|
56
|
+
* A PIN pairing runs M1 to M6 and yields long-term credentials. A transient pairing stops after M4
|
|
57
|
+
* with the fixed {@link TRANSIENT_PAIRING_PIN} and yields session keys only. The steps are public
|
|
58
|
+
* for a caller that has to wait for the PIN between M1 and M2.
|
|
59
|
+
*/
|
|
60
|
+
declare class PairSetup {
|
|
61
|
+
#private;
|
|
62
|
+
constructor(context: Context, transport: PairingTransport, options?: PairingOptions);
|
|
63
|
+
/** Generates the controller's long-term Ed25519 key pair. Call before {@link pin}. */
|
|
64
|
+
start(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Runs a PIN pairing from M1 to M6. It calls `askPin` after M1, once the accessory shows the PIN.
|
|
67
|
+
*
|
|
68
|
+
* @throws {PairingError} If a step fails.
|
|
69
|
+
*/
|
|
70
|
+
pin(askPin: () => Promise<string>): Promise<AccessoryCredentials>;
|
|
71
|
+
/** Runs a transient pairing from M1 to M4 without a PIN. The keys hold for this connection only. */
|
|
72
|
+
transient(): Promise<AccessoryKeys>;
|
|
73
|
+
/** Asks the accessory for its SRP public key and salt. */
|
|
74
|
+
m1(additionalTlv?: [number, number | Buffer][]): Promise<PairM1>;
|
|
75
|
+
/** Computes the SRP public key and the proof that we know the PIN. Sends nothing. */
|
|
76
|
+
m2(m1: PairM1, pin?: string): Promise<PairM2>;
|
|
77
|
+
/** Sends our SRP public key and proof, and receives the accessory's proof. */
|
|
78
|
+
m3(m2: PairM2): Promise<PairM3>;
|
|
79
|
+
/** Checks the accessory's proof and derives the SRP shared secret. Sends nothing. */
|
|
80
|
+
m4(m3: PairM3): Promise<PairM4>;
|
|
81
|
+
/** Sends our signed, encrypted identity and receives the accessory's encrypted identity. */
|
|
82
|
+
m5(m4: PairM4): Promise<PairM5>;
|
|
83
|
+
/**
|
|
84
|
+
* Decrypts and verifies the accessory's identity from M5. Sends nothing.
|
|
85
|
+
*
|
|
86
|
+
* @throws {AuthenticationError} If the accessory signature is invalid.
|
|
87
|
+
*/
|
|
88
|
+
m6(m4: PairM4, m5: PairM5): Promise<AccessoryCredentials>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Runs HAP pair-verify as the controller. An ephemeral Curve25519 exchange proves both long-term
|
|
92
|
+
* identities from an earlier pair-setup, so every session gets fresh keys without the PIN.
|
|
93
|
+
*/
|
|
94
|
+
declare class PairVerify {
|
|
95
|
+
#private;
|
|
96
|
+
constructor(context: Context, transport: PairingTransport, options?: PairingOptions);
|
|
97
|
+
/**
|
|
98
|
+
* Verifies the pairing and returns the shared secret. The channel keys stay empty, because
|
|
99
|
+
* each protocol derives its own from the secret.
|
|
100
|
+
*
|
|
101
|
+
* @throws {AuthenticationError} If the accessory's identity does not match the credentials.
|
|
102
|
+
*/
|
|
103
|
+
start(credentials: AccessoryCredentials): Promise<AccessoryKeys>;
|
|
104
|
+
}
|
|
105
|
+
type PairM1 = {
|
|
106
|
+
readonly publicKey: Buffer;
|
|
107
|
+
readonly salt: Buffer;
|
|
108
|
+
};
|
|
109
|
+
type PairM2 = {
|
|
110
|
+
readonly publicKey: Buffer;
|
|
111
|
+
readonly proof: Buffer;
|
|
112
|
+
};
|
|
113
|
+
type PairM3 = {
|
|
114
|
+
readonly serverProof: Buffer;
|
|
115
|
+
};
|
|
116
|
+
type PairM4 = {
|
|
117
|
+
readonly sharedSecret: Buffer;
|
|
118
|
+
};
|
|
119
|
+
type PairM5 = {
|
|
120
|
+
/** The sealed identity of the accessory, which {@link PairSetup.m6} opens. */readonly encryptedData: Buffer;
|
|
121
|
+
readonly sessionKey: Buffer;
|
|
122
|
+
};
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/pairing/const.d.ts
|
|
125
|
+
/** The fixed setup code of a HAP transient pair-setup. */
|
|
126
|
+
declare const TRANSIENT_PAIRING_PIN = "3939";
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/pairing/server.d.ts
|
|
129
|
+
/**
|
|
130
|
+
* Answers HAP pair-setup as the accessory, M1, M3 and M5 with M2, M4 and M6. After M5,
|
|
131
|
+
* {@link controller} holds the verified controller identity to persist.
|
|
132
|
+
*/
|
|
133
|
+
declare class PairSetupServer {
|
|
134
|
+
#private;
|
|
135
|
+
get controller(): PairedController | undefined;
|
|
136
|
+
/** The SRP session key, available after M3. */
|
|
137
|
+
get sharedSecret(): Buffer | undefined;
|
|
138
|
+
constructor(context: Context, identity: AccessoryIdentity, pin: string, options?: PairingOptions);
|
|
139
|
+
/**
|
|
140
|
+
* Answers one pair-setup request with the next message.
|
|
141
|
+
*
|
|
142
|
+
* @throws {PairingError} If the request carries an unexpected state.
|
|
143
|
+
* @throws {AuthenticationError} If the PIN proof or the controller signature is wrong.
|
|
144
|
+
*/
|
|
145
|
+
handle(request: Buffer): Promise<Buffer>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Answers HAP pair-verify as the accessory, M1 and M3 with M2 and M4. Once M3 verifies the
|
|
149
|
+
* controller, {@link sharedSecret} feeds the channel key derivation.
|
|
150
|
+
*/
|
|
151
|
+
declare class PairVerifyServer {
|
|
152
|
+
#private;
|
|
153
|
+
/** The pairing identifier of the verified controller, available after M3. */
|
|
154
|
+
get pairingId(): Buffer | undefined;
|
|
155
|
+
/** The Curve25519 shared secret, available after M1. */
|
|
156
|
+
get sharedSecret(): Buffer | undefined;
|
|
157
|
+
constructor(context: Context, identity: AccessoryIdentity, resolveController: ControllerResolver, options?: PairingOptions);
|
|
158
|
+
/**
|
|
159
|
+
* Answers one pair-verify request with the next message.
|
|
160
|
+
*
|
|
161
|
+
* @throws {PairingError} If the request carries an unexpected state.
|
|
162
|
+
* @throws {AuthenticationError} If the controller is unknown or its signature is wrong.
|
|
163
|
+
*/
|
|
164
|
+
handle(request: Buffer): Promise<Buffer>;
|
|
165
|
+
}
|
|
166
|
+
/** Generates an accessory identity with a random MAC-style identifier and a new Ed25519 key pair. */
|
|
167
|
+
declare function generateAccessoryIdentity(): AccessoryIdentity;
|
|
168
|
+
//#endregion
|
|
169
|
+
export { type AccessoryCredentials, type AccessoryIdentity, type AccessoryKeys, type ControllerResolver, PairSetup, PairSetupServer, PairVerify, PairVerifyServer, type PairedController, type PairingOptions, type PairingStep, type PairingTransport, TRANSIENT_PAIRING_PIN, deriveControlKeys, generateAccessoryIdentity };
|