@basmilius/apple-common 0.0.76 → 0.0.77
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/dist/index.js +2 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)),t--,t===0)throw Error("Device not found after serveral tries, aborting.");await U(r)}}static airplay(){return new P(D)}static companionLink(){return new P(k)}static raop(){return new P(R)}}import{networkInterfaces as pe}from"node:os";function C(){let e=pe();for(let t of Object.keys(e)){let r=e[t];if(!r)continue;for(let o of r){if(o.internal||o.family!=="IPv4")continue;if(o.address&&o.address!=="127.0.0.1")return o.address}}return null}import{networkInterfaces as he}from"node:os";function N(){let e=he();for(let t of Object.keys(e)){let r=e[t];if(!r)continue;for(let o of r){if(o.internal||o.family!=="IPv4")continue;if(o.mac&&o.mac!=="00:00:00:00:00:00")return o.mac.toUpperCase()}}return"00:00:00:00:00:00"}import{EventEmitter as ge}from"node:events";class M extends ge{get address(){return this.#e}get port(){return this.#r}#e;#r;constructor(e,t){super();this.#e=e,this.#r=t}async connect(){}async disconnect(){}async onClose(){this.emit("close")}async onConnect(){this.emit("connect")}async onError(e){this.emit("error",e)}async onTimeout(){this.emit("timeout")}}import{createSocket as Ce}from"node:dgram";import{parse as xe}from"@plist/binary.parse";import{serialize as Fe}from"@plist/binary.serialize";var Pe=Object.defineProperty,x=(e,t)=>{for(var r in t)Pe(e,r,{get:t[r],enumerable:!0,configurable:!0,set:(o)=>t[r]=()=>o})},E={};x(E,{parts:()=>Be,ns:()=>W,now:()=>we,encode:()=>Ie,decode:()=>ve});var be=0x83AA7E80n;function we(){let e=W()/1000n,t=e/1000000n,r=e-t*1000000n;return t+be<<32n|(r<<32n)/1000000n}function W(){return process.hrtime.bigint()}function Be(e){return[Number(e>>32n),Number(e&0xFFFFFFFFn)]}function ve(e){return{proto:e.readUInt8(0),type:e.readUInt8(1),seqno:e.readUInt16BE(2),padding:e.readUInt32BE(4),reftime_sec:e.readUInt32BE(8),reftime_frac:e.readUInt32BE(12),recvtime_sec:e.readUInt32BE(16),recvtime_frac:e.readUInt32BE(20),sendtime_sec:e.readUInt32BE(24),sendtime_frac:e.readUInt32BE(28)}}function Ie(e){let t=Buffer.alloc(32);return t.writeUInt8(e.proto,0),t.writeUInt8(e.type,1),t.writeUInt16BE(e.seqno,2),t.writeUInt32BE(e.padding,4),t.writeUInt32BE(e.reftime_sec,8),t.writeUInt32BE(e.reftime_frac,12),t.writeUInt32BE(e.recvtime_sec,16),t.writeUInt32BE(e.recvtime_frac,20),t.writeUInt32BE(e.sendtime_sec,24),t.writeUInt32BE(e.sendtime_frac,28),t}var O={};x(O,{sizedInt:()=>J,int:()=>Se,float:()=>Ee,encode:()=>Ke,decode:()=>Ae});class L extends Number{size;constructor(e,t){super(e);this.size=t}}class q{value;constructor(e){this.value=e}}class ${value;constructor(e){this.value=e}}function J(e,t){return new L(e,t)}function Ee(e){return new q(e)}function Se(e){return new $(e)}function u(e){let t=e.reduce((n,s)=>n+s.length,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}function c(e){return Uint8Array.of(e)}function y(e,t){let r=new Uint8Array(t),o=BigInt(e);for(let n=0;n<t;n++)r[n]=Number(o&0xffn),o>>=8n;return r}function b(e){let t=e.reduce((n,s)=>n+s.length,0),r=new Uint8Array(t),o=0;for(let n of e)r.set(n,o),o+=n.length;return r}function Ke(e){return V(e,[])}function V(e,t){let r=null;if(e===null||e===void 0)r=c(4);else if(typeof e==="boolean")r=c(e?1:2);else if(e instanceof q){let n=new ArrayBuffer(8);new DataView(n).setFloat64(0,e.value,!0),r=u([c(54),new Uint8Array(n)])}else if(e instanceof $){let n=e.value;if(n<40)r=c(8+n);else if(n<=255)r=b([c(48),y(n,1)]);else if(n<=65535)r=b([c(49),y(n,2)]);else if(n<=4294967295)r=b([c(50),y(n,4)]);else r=b([c(51),y(n,8)])}else if(typeof e==="number")if(!Number.isInteger(e)){let n=new ArrayBuffer(8);new DataView(n).setFloat64(0,e,!0),r=u([c(54),new Uint8Array(n)])}else if(e<40)r=c(8+e);else if(e<=255)r=u([c(48),y(e,1)]);else if(e<=65535)r=u([c(49),y(e,2)]);else if(e<=4294967295)r=u([c(50),y(e,4)]);else r=u([c(51),y(e,8)]);else if(e instanceof L)r=u([c(48+Math.log2(e.size)),y(e.valueOf(),e.size)]);else if(typeof e==="string"){let n=new TextEncoder().encode(e),s=n.length;if(s<=32)r=u([c(64+s),n]);else if(s<=255)r=u([c(97),y(s,1),n]);else if(s<=65535)r=u([c(98),y(s,2),n]);else if(s<=16777215)r=u([c(99),y(s,3),n]);else r=u([c(100),y(s,4),n])}else if(e instanceof Uint8Array||Buffer.isBuffer(e)){let n=e instanceof Uint8Array?e:new Uint8Array(e),s=n.length;if(s<=32)r=u([c(112+s),n]);else if(s<=255)r=u([c(145),y(s,1),n]);else if(s<=65535)r=u([c(146),y(s,2),n]);else r=u([c(147),y(s,4),n])}else if(Array.isArray(e)){let n=u(e.map((a)=>V(a,t))),s=e.length;if(s<=15){if(r=u([c(208+s),n]),s>=15)r=u([r,c(3)])}else r=u([c(223),n,c(3)])}else if(typeof e==="object"){let n=Object.keys(e),s=n.length,a=[];for(let l of n)a.push(V(l,t)),a.push(V(e[l],t));let f;if(s<=15)f=c(224+s);else f=c(239);if(r=b([f,b(a)]),s>=15||t.some((l)=>l===r))r=b([r,c(129)])}else throw TypeError(typeof e);let o=t.findIndex((n)=>n.length===r.length&&n.every((s,a)=>s===r[a]));if(o>=0)if(o<33)r=c(160+o);else if(o<=255)r=u([c(193),y(o,1)]);else if(o<=65535)r=u([c(194),y(o,2)]);else if(o<=4294967295)r=u([c(195),y(o,4)]);else r=u([c(196),y(o,8)]);else if(r.length>1)t.push(r);return r}function Ae(e){let[t]=w(e,[]);return t}function Me(e,t){if(e.length<t)throw TypeError(`Not enough data: need ${t} bytes, have ${e.length}`)}function K(e,t,r){Me(e.subarray(t),r);let o=0n;for(let n=r-1;n>=0;n--)o=o<<8n|BigInt(e[t+n]);return Number(o)}function w(e,t){if(e.length===0)throw TypeError("No data to unpack");let r=e[0],o=!0,n,s;if(r===1)n=!0,s=e.subarray(1);else if(r===2)n=!1,s=e.subarray(1);else if(r===4)n=null,s=e.subarray(1);else if(r===5)n=e.subarray(1,17),s=e.subarray(17);else if(r===6)n=K(e,1,8),s=e.subarray(9);else if(r>=8&&r<=47)n=r-8,s=e.subarray(1);else if(r===53)n=new DataView(e.buffer,e.byteOffset+1,4).getFloat32(0,!0),s=e.subarray(5);else if(r===54)n=new DataView(e.buffer,e.byteOffset+1,8).getFloat64(0,!0),s=e.subarray(9);else if((r&240)===48){let a=2**(r&15),f=K(e,1,a);n=J(f,a),s=e.subarray(1+a)}else if(r>=64&&r<=96){let a=r-64;n=new TextDecoder().decode(e.subarray(1,1+a)),s=e.subarray(1+a)}else if(r>=97&&r<=100){let a=r&15,f=K(e,1,a);n=new TextDecoder().decode(e.subarray(1+a,1+a+f)),s=e.subarray(1+a+f)}else if(r>=112&&r<=144){let a=r-112;n=e.subarray(1,1+a),s=e.subarray(1+a)}else if(r>=145&&r<=148){let a=1<<(r&15)-1,f=K(e,1,a),l=1+a;n=e.subarray(l,l+f),s=e.subarray(l+f)}else if((r&240)===208){let a=r&15,f=e.subarray(1),l=[];if(a===15){while(f[0]!==3){let[d,m]=w(f,t);l.push(d),f=m}f=f.subarray(1)}else for(let d=0;d<a;d++){let[m,p]=w(f,t);l.push(m),f=p}n=l,s=f,o=!1}else if((r&224)===224){let a=r&15,f=e.subarray(1),l={};if(a===15){while(f[0]!==3){let[d,m]=w(f,t),[p,S]=w(m,t);l[d]=p,f=S}f=f.subarray(1)}else for(let d=0;d<a;d++){let[m,p]=w(f,t),[S,H]=w(p,t);l[m]=S,f=H}n=l,s=f,o=!1}else if(r>=160&&r<=192){let a=r-160;if(a>=t.length)throw TypeError(`Reference index ${a} out of range`);n=t[a],s=e.subarray(1),o=!1}else if(r>=193&&r<=196){let a=r-192,f=K(e,1,a);if(f>=t.length)throw TypeError(`UID ${f} out of range`);n=t[f],s=e.subarray(1+a),o=!1}else throw TypeError(`Unknown tag 0x${r.toString(16)}`);if(o)t.push(n);return[n,s]}var Ve={};x(Ve,{serialize:()=>Fe,parse:()=>xe});var i={};x(i,{encode:()=>ke,decode:()=>Re,bail:()=>De,Value:()=>I,State:()=>_e,Method:()=>Ue,Flags:()=>Te,ErrorCode:()=>Q});var Te={TransientPairing:16},Q={Unknown:1,Authentication:2,BackOff:3,MaxPeers:4,MaxTries:5,Unavailable:6,Busy:7},Ue={PairSetup:0,PairSetupWithAuth:1,PairVerify:2,AddPairing:3,RemovePairing:4,ListPairing:5},_e={M1:1,M2:2,M3:3,M4:4,M5:5,M6:6},I={Method:0,Identifier:1,Salt:2,PublicKey:3,Proof:4,EncryptedData:5,State:6,Error:7,BackOff:8,Certificate:9,Signature:10,Permissions:11,FragmentData:12,FragmentLast:13,Name:17,Flags:19};function De(e){if(e.has(I.BackOff)){let t=e.get(I.BackOff),r=t.readUintLE(0,t.length);throw Error(`Device is busy, try again in ${r} seconds.`)}if(e.has(I.Error)){let t=Object.entries(Q).find(([r,o])=>o===e.get(I.Error).readUint8());if(!t)throw Error(`Device returned an unknown error code: ${e.get(I.Error).readUint8()}`);throw Error(`Device returned an error code: ${t[0]}`)}throw Error("Invalid response")}function ke(e){let t=[];for(let[r,o]of e){let n;if(typeof o==="number")n=Buffer.from([o]);else n=o;let s=0;do{let a=Math.min(n.length-s,255);if(t.push(r,a),a>0)for(let f=0;f<a;f++)t.push(n[s+f]);s+=a}while(s<n.length)}return Buffer.from(t)}function Re(e){let t=new Map,r=0;while(r<e.length){let o=e[r++],n=e[r++],s=new Uint8Array(e).slice(r,r+n);r+=n;let a=t.get(o);if(a)t.set(o,Buffer.concat([a,s]));else t.set(o,Buffer.from(s))}return t}class Z{get port(){return this.#r}#e;#r=0;constructor(){this.#e=Ce("udp4"),this.#e.on("error",(e)=>this.#t(e)),this.#e.on("message",(e,t)=>this.#s(e,t))}async close(){this.#e.close(),this.#r=0}async listen(){return new Promise((e)=>{this.#e.once("listening",()=>this.#n()),this.#e.bind(0,e)})}async#t(e){v.error("Timing server error",e)}async#n(){let{port:e}=this.#e.address();this.#r=e}async#s(e,t){let r=E.decode(e),o=E.now(),[n,s]=E.parts(o);v.info(`Timing server ntp=${o} receivedSeconds=${n} receivedFraction=${s}`);let a=E.encode({proto:r.proto,type:211,seqno:r.seqno,padding:0,reftime_sec:r.sendtime_sec,reftime_frac:r.sendtime_frac,recvtime_sec:n,recvtime_frac:s,sendtime_sec:n,sendtime_frac:s});this.#e.send(a,t.port,t.address)}}import{SRP as ee,SrpClient as Ne}from"fast-srp-hap";import{v4 as Oe}from"uuid";import A from"tweetnacl";class re{#e;#r;#t;#n;#s;#o;constructor(e){this.#e="basmilius/apple-protocols",this.#r=Buffer.from(Oe().toUpperCase()),this.#t=e}async start(){let e=A.sign.keyPair();this.#n=Buffer.from(e.publicKey),this.#s=Buffer.from(e.secretKey)}async pin(e){let t=await this.m1(),r=await this.m2(t,await e()),o=await this.m3(r),n=await this.m4(o),s=await this.m5(n),a=await this.m6(n,s);if(!a)throw Error("Pairing failed, could not get accessory keys.");return a}async transient(){let e=await this.m1([[i.Value.Flags,i.Flags.TransientPairing]]),t=await this.m2(e),r=await this.m3(t),o=await this.m4(r),n=h({hash:"sha512",key:o.sharedSecret,length:32,salt:Buffer.from("Control-Salt"),info:Buffer.from("Control-Read-Encryption-Key")}),s=h({hash:"sha512",key:o.sharedSecret,length:32,salt:Buffer.from("Control-Salt"),info:Buffer.from("Control-Write-Encryption-Key")});return{pairingId:this.#r,sharedSecret:o.sharedSecret,accessoryToControllerKey:n,controllerToAccessoryKey:s}}async m1(e=[]){let t=await this.#t("m1",i.encode([[i.Value.Method,i.Method.PairSetup],[i.Value.State,i.State.M1],...e])),r=F(t),o=r.get(i.Value.PublicKey),n=r.get(i.Value.Salt);return{publicKey:o,salt:n}}async m2(e,t=_){let r=await ee.genKey(32);this.#o=new Ne(ee.params.hap,e.salt,Buffer.from("Pair-Setup"),Buffer.from(t),r,!0),this.#o.setB(e.publicKey);let o=this.#o.computeA(),n=this.#o.computeM1();return{publicKey:o,proof:n}}async m3(e){let t=await this.#t("m3",i.encode([[i.Value.State,i.State.M3],[i.Value.PublicKey,e.publicKey],[i.Value.Proof,e.proof]]));return{serverProof:F(t).get(i.Value.Proof)}}async m4(e){return this.#o.checkM2(e.serverProof),{sharedSecret:this.#o.computeK()}}async m5(e){let t=h({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Controller-Sign-Salt","utf8"),info:Buffer.from("Pair-Setup-Controller-Sign-Info","utf8")}),r=h({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Encrypt-Salt","utf8"),info:Buffer.from("Pair-Setup-Encrypt-Info","utf8")}),o=Buffer.concat([t,this.#r,this.#n]),n=A.sign.detached(o,this.#s),s=i.encode([[i.Value.Identifier,this.#r],[i.Value.PublicKey,this.#n],[i.Value.Signature,Buffer.from(n)],[i.Value.Name,Buffer.from(O.encode({name:this.#e}))]]),{authTag:a,ciphertext:f}=g.encrypt(r,Buffer.from("PS-Msg05"),null,s),l=Buffer.concat([f,a]),d=await this.#t("m5",i.encode([[i.Value.State,i.State.M5],[i.Value.EncryptedData,l]])),p=F(d).get(i.Value.EncryptedData),S=p.subarray(0,-16);return{authTag:p.subarray(-16),data:S,sessionKey:r}}async m6(e,t){let r=g.decrypt(t.sessionKey,Buffer.from("PS-Msg06"),null,t.data,t.authTag),o=i.decode(r),n=o.get(i.Value.Identifier),s=o.get(i.Value.PublicKey),a=o.get(i.Value.Signature),f=h({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Accessory-Sign-Salt"),info:Buffer.from("Pair-Setup-Accessory-Sign-Info")}),l=Buffer.concat([f,n,s]);if(!A.sign.detached.verify(l,a,s))throw Error("Invalid accessory signature.");return{accessoryIdentifier:n.toString(),accessoryLongTermPublicKey:s,pairingId:this.#r,publicKey:this.#n,secretKey:this.#s}}}class te{#e;#r;constructor(e){this.#e=B.generateKeyPair(),this.#r=e}async start(e){let t=await this.#t(),r=await this.#n(e.accessoryIdentifier,e.accessoryLongTermPublicKey,t);return await this.#s(e.pairingId,e.secretKey,r),await this.#o(r,e.pairingId)}async#t(){let e=await this.#r("m1",i.encode([[i.Value.State,i.State.M1],[i.Value.PublicKey,Buffer.from(this.#e.publicKey)]])),t=F(e),r=t.get(i.Value.PublicKey);return{encryptedData:t.get(i.Value.EncryptedData),serverPublicKey:r}}async#n(e,t,r){let o=Buffer.from(B.generateSharedSecKey(this.#e.secretKey,r.serverPublicKey)),n=h({hash:"sha512",key:o,length:32,salt:Buffer.from("Pair-Verify-Encrypt-Salt"),info:Buffer.from("Pair-Verify-Encrypt-Info")}),s=r.encryptedData.subarray(0,-16),a=r.encryptedData.subarray(-16),f=g.decrypt(n,Buffer.from("PV-Msg02"),null,s,a),l=i.decode(f),d=l.get(i.Value.Identifier),m=l.get(i.Value.Signature);if(d.toString()!==e)throw Error(`Invalid accessory identifier. Expected ${d.toString()} to be ${e}.`);let p=Buffer.concat([r.serverPublicKey,d,this.#e.publicKey]);if(!A.sign.detached.verify(p,m,t))throw Error("Invalid accessory signature.");return{serverEphemeralPublicKey:r.serverPublicKey,sessionKey:n,sharedSecret:o}}async#s(e,t,r){let o=Buffer.concat([this.#e.publicKey,e,r.serverEphemeralPublicKey]),n=Buffer.from(A.sign.detached(o,t)),s=i.encode([[i.Value.Identifier,e],[i.Value.Signature,n]]),{authTag:a,ciphertext:f}=g.encrypt(r.sessionKey,Buffer.from("PV-Msg03"),null,s),l=Buffer.concat([f,a]);return await this.#r("m3",i.encode([[i.Value.State,i.State.M3],[i.Value.EncryptedData,l]])),{}}async#o(e,t){return{accessoryToControllerKey:Buffer.alloc(0),controllerToAccessoryKey:Buffer.alloc(0),pairingId:t,sharedSecret:e.sharedSecret}}}function F(e){let t=i.decode(e);if(t.has(i.Value.Error))i.bail(t);return v.raw("Decoded TLV",t),t}function Le(e){let t=Buffer.alloc(2);return t.writeUInt16BE(e,0),t}function qe(e){let[t,r]=$e(e),o=Buffer.alloc(8);return o.writeUInt32LE(r,0),o.writeUInt32LE(t,4),o}function $e(e){if(e<=-1||e>9007199254740991)throw Error("Number out of range.");if(Math.floor(e)!==e)throw Error("Number is not an integer.");let o=0,n=e&4294967295,s=n<0?(e&2147483647)+2147483648:n;if(e>4294967295)o=(e-s)/4294967296;return[o,s]}export{U as waitFor,Cr as uuid,qe as uint53ToLE,Le as uint16ToBE,v as reporter,ye as prompt,h as hkdf,N as getMacAddress,C as getLocalIP,Y as cli,Z as TimingServer,R as RAOP_SERVICE,de as HTTP_TIMEOUT,P as Discovery,B as Curve25519,g as Chacha20,k as COMPANION_LINK_SERVICE,M as BaseSocket,te as AccessoryVerify,re as AccessoryPair,_ as AIRPLAY_TRANSIENT_PIN,D as AIRPLAY_SERVICE};
|
|
1
|
+
var U=Object.defineProperty;var x=(e,r)=>{for(var t in r)U(e,t,{get:r[t],enumerable:!0,configurable:!0,set:(o)=>r[t]=()=>o})};import{v4 as er}from"uuid";var u={};x(u,{padNonce:()=>S,encrypt:()=>$,decrypt:()=>H});import{createCipher as q,createDecipher as O}from"chacha";var T=12;function H(e,r,t,o,n){r=S(r);let a=O(e,r);t&&a.setAAD(t),a.setAuthTag(n);let i=a._update(o);return a._final(),i}function $(e,r,t,o){r=S(r);let n=q(e,r);t&&n.setAAD(t);let a=n._update(o);n._final();let i=n.getAuthTag();return{ciphertext:a,authTag:i}}function S(e){if(e.length>=T)return e;return Buffer.concat([Buffer.alloc(T-e.length,0),e])}var d={};x(d,{generateSharedSecKey:()=>Y,generateKeyPair:()=>X});import F from"tweetnacl";function X(){let e=F.box.keyPair();return{publicKey:e.publicKey,secretKey:e.secretKey}}function Y(e,r){return F.scalarMult(e,r)}import{hkdfSync as G}from"node:crypto";function c(e){return Buffer.from(G(e.hash,e.key,e.salt,e.info,e.length))}import J from"node-dns-sd";import{createInterface as j}from"node:readline";var R=j({input:process.stdin,output:process.stdout});async function W(e){return await new Promise((r)=>R.question(`${e}: `,r))}async function v(e){return new Promise((r)=>setTimeout(r,e))}class C{#e=[];all(){this.#e=["error","info","net","raw","warn"]}disable(e){if(this.#e.includes(e))this.#e.splice(this.#e.indexOf(e),1)}enable(e){if(!this.#e.includes(e))this.#e.push(e)}isEnabled(e){return this.#e.includes(e)}error(...e){this.isEnabled("error")&&console.error("\x1B[31m[error]\x1B[39m",...e)}info(...e){this.isEnabled("info")&&console.info("\x1B[32m[info]\x1B[39m",...e)}net(...e){this.isEnabled("net")&&console.info("\x1B[33m[net]\x1B[39m",...e)}raw(...e){this.isEnabled("raw")&&console.log("\x1B[34m[raw]\x1B[39m",...e)}warn(...e){this.isEnabled("warn")&&console.warn("\x1B[33m[warn]\x1B[39m",...e)}}var m=new C;var K="3939",z=1750,w="_airplay._tcp.local",I="_companion-link._tcp.local",E="_raop._tcp.local";class l{#e;constructor(e){this.#e=e}async find(){return await J.discover({name:this.#e})}async findUntil(e,r=10,t=1000){while(r>0){let o=await this.find(),n=o.find((a)=>a.fqdn===e);if(n)return n;if(console.log(),console.log(`Device not found, retrying in ${t}ms...`),console.log(o.map((a)=>` ● ${a.fqdn}`).join(`
|
|
2
|
+
`)),r--,r===0)throw Error("Device not found after serveral tries, aborting.");await v(t)}}static airplay(){return new l(w)}static companionLink(){return new l(I)}static raop(){return new l(E)}}import{networkInterfaces as Q}from"node:os";function M(){let e=Q();for(let r of Object.keys(e)){let t=e[r];if(!t)continue;for(let o of t){if(o.internal||o.family!=="IPv4")continue;if(o.address&&o.address!=="127.0.0.1")return o.address}}return null}import{networkInterfaces as Z}from"node:os";function V(){let e=Z();for(let r of Object.keys(e)){let t=e[r];if(!t)continue;for(let o of t){if(o.internal||o.family!=="IPv4")continue;if(o.mac&&o.mac!=="00:00:00:00:00:00")return o.mac.toUpperCase()}}return"00:00:00:00:00:00"}import{EventEmitter as ee}from"node:events";class g extends ee{get address(){return this.#e}get port(){return this.#r}#e;#r;constructor(e,r){super();this.#e=e,this.#r=r}async connect(){}async disconnect(){}async onClose(){this.emit("close")}async onConnect(){this.emit("connect")}async onError(e){this.emit("error",e)}async onTimeout(){this.emit("timeout")}}import{createSocket as re}from"node:dgram";import{NTP as b}from"@basmilius/apple-encoding";class _{get port(){return this.#r}#e;#r=0;constructor(){this.#e=re("udp4"),this.#e.on("error",(e)=>this.#t(e)),this.#e.on("message",(e,r)=>this.#n(e,r))}async close(){this.#e.close(),this.#r=0}async listen(){return new Promise((e)=>{this.#e.once("listening",()=>this.#o()),this.#e.bind(0,e)})}async#t(e){m.error("Timing server error",e)}async#o(){let{port:e}=this.#e.address();this.#r=e}async#n(e,r){let t=b.decode(e),o=b.now(),[n,a]=b.parts(o);m.info(`Timing server ntp=${o} receivedSeconds=${n} receivedFraction=${a}`);let i=b.encode({proto:t.proto,type:211,seqno:t.seqno,padding:0,reftime_sec:t.sendtime_sec,reftime_frac:t.sendtime_frac,recvtime_sec:n,recvtime_frac:a,sendtime_sec:n,sendtime_frac:a});this.#e.send(i,r.port,r.address)}}import{OPack as te,TLV8 as s}from"@basmilius/apple-encoding";import{SRP as D,SrpClient as oe}from"fast-srp-hap";import{v4 as se}from"uuid";import h from"tweetnacl";class k{#e;#r;#t;#o;#n;#s;constructor(e){this.#e="basmilius/apple-protocols",this.#r=Buffer.from(se().toUpperCase()),this.#t=e}async start(){let e=h.sign.keyPair();this.#o=Buffer.from(e.publicKey),this.#n=Buffer.from(e.secretKey)}async pin(e){let r=await this.m1(),t=await this.m2(r,await e()),o=await this.m3(t),n=await this.m4(o),a=await this.m5(n),i=await this.m6(n,a);if(!i)throw Error("Pairing failed, could not get accessory keys.");return i}async transient(){let e=await this.m1([[s.Value.Flags,s.Flags.TransientPairing]]),r=await this.m2(e),t=await this.m3(r),o=await this.m4(t),n=c({hash:"sha512",key:o.sharedSecret,length:32,salt:Buffer.from("Control-Salt"),info:Buffer.from("Control-Read-Encryption-Key")}),a=c({hash:"sha512",key:o.sharedSecret,length:32,salt:Buffer.from("Control-Salt"),info:Buffer.from("Control-Write-Encryption-Key")});return{pairingId:this.#r,sharedSecret:o.sharedSecret,accessoryToControllerKey:n,controllerToAccessoryKey:a}}async m1(e=[]){let r=await this.#t("m1",s.encode([[s.Value.Method,s.Method.PairSetup],[s.Value.State,s.State.M1],...e])),t=B(r),o=t.get(s.Value.PublicKey),n=t.get(s.Value.Salt);return{publicKey:o,salt:n}}async m2(e,r=K){let t=await D.genKey(32);this.#s=new oe(D.params.hap,e.salt,Buffer.from("Pair-Setup"),Buffer.from(r),t,!0),this.#s.setB(e.publicKey);let o=this.#s.computeA(),n=this.#s.computeM1();return{publicKey:o,proof:n}}async m3(e){let r=await this.#t("m3",s.encode([[s.Value.State,s.State.M3],[s.Value.PublicKey,e.publicKey],[s.Value.Proof,e.proof]]));return{serverProof:B(r).get(s.Value.Proof)}}async m4(e){return this.#s.checkM2(e.serverProof),{sharedSecret:this.#s.computeK()}}async m5(e){let r=c({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Controller-Sign-Salt","utf8"),info:Buffer.from("Pair-Setup-Controller-Sign-Info","utf8")}),t=c({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Encrypt-Salt","utf8"),info:Buffer.from("Pair-Setup-Encrypt-Info","utf8")}),o=Buffer.concat([r,this.#r,this.#o]),n=h.sign.detached(o,this.#n),a=s.encode([[s.Value.Identifier,this.#r],[s.Value.PublicKey,this.#o],[s.Value.Signature,Buffer.from(n)],[s.Value.Name,Buffer.from(te.encode({name:this.#e}))]]),{authTag:i,ciphertext:y}=u.encrypt(t,Buffer.from("PS-Msg05"),null,a),f=Buffer.concat([y,i]),p=await this.#t("m5",s.encode([[s.Value.State,s.State.M5],[s.Value.EncryptedData,f]])),P=B(p).get(s.Value.EncryptedData),N=P.subarray(0,-16);return{authTag:P.subarray(-16),data:N,sessionKey:t}}async m6(e,r){let t=u.decrypt(r.sessionKey,Buffer.from("PS-Msg06"),null,r.data,r.authTag),o=s.decode(t),n=o.get(s.Value.Identifier),a=o.get(s.Value.PublicKey),i=o.get(s.Value.Signature),y=c({hash:"sha512",key:e.sharedSecret,length:32,salt:Buffer.from("Pair-Setup-Accessory-Sign-Salt"),info:Buffer.from("Pair-Setup-Accessory-Sign-Info")}),f=Buffer.concat([y,n,a]);if(!h.sign.detached.verify(f,i,a))throw Error("Invalid accessory signature.");return{accessoryIdentifier:n.toString(),accessoryLongTermPublicKey:a,pairingId:this.#r,publicKey:this.#o,secretKey:this.#n}}}class L{#e;#r;constructor(e){this.#e=d.generateKeyPair(),this.#r=e}async start(e){let r=await this.#t(),t=await this.#o(e.accessoryIdentifier,e.accessoryLongTermPublicKey,r);return await this.#n(e.pairingId,e.secretKey,t),await this.#s(t,e.pairingId)}async#t(){let e=await this.#r("m1",s.encode([[s.Value.State,s.State.M1],[s.Value.PublicKey,Buffer.from(this.#e.publicKey)]])),r=B(e),t=r.get(s.Value.PublicKey);return{encryptedData:r.get(s.Value.EncryptedData),serverPublicKey:t}}async#o(e,r,t){let o=Buffer.from(d.generateSharedSecKey(this.#e.secretKey,t.serverPublicKey)),n=c({hash:"sha512",key:o,length:32,salt:Buffer.from("Pair-Verify-Encrypt-Salt"),info:Buffer.from("Pair-Verify-Encrypt-Info")}),a=t.encryptedData.subarray(0,-16),i=t.encryptedData.subarray(-16),y=u.decrypt(n,Buffer.from("PV-Msg02"),null,a,i),f=s.decode(y),p=f.get(s.Value.Identifier),A=f.get(s.Value.Signature);if(p.toString()!==e)throw Error(`Invalid accessory identifier. Expected ${p.toString()} to be ${e}.`);let P=Buffer.concat([t.serverPublicKey,p,this.#e.publicKey]);if(!h.sign.detached.verify(P,A,r))throw Error("Invalid accessory signature.");return{serverEphemeralPublicKey:t.serverPublicKey,sessionKey:n,sharedSecret:o}}async#n(e,r,t){let o=Buffer.concat([this.#e.publicKey,e,t.serverEphemeralPublicKey]),n=Buffer.from(h.sign.detached(o,r)),a=s.encode([[s.Value.Identifier,e],[s.Value.Signature,n]]),{authTag:i,ciphertext:y}=u.encrypt(t.sessionKey,Buffer.from("PV-Msg03"),null,a),f=Buffer.concat([y,i]);return await this.#r("m3",s.encode([[s.Value.State,s.State.M3],[s.Value.EncryptedData,f]])),{}}async#s(e,r){return{accessoryToControllerKey:Buffer.alloc(0),controllerToAccessoryKey:Buffer.alloc(0),pairingId:r,sharedSecret:e.sharedSecret}}}function B(e){let r=s.decode(e);if(r.has(s.Value.Error))s.bail(r);return m.raw("Decoded TLV",r),r}function ne(e){let r=Buffer.alloc(2);return r.writeUInt16BE(e,0),r}function ae(e){let[r,t]=ie(e),o=Buffer.alloc(8);return o.writeUInt32LE(t,0),o.writeUInt32LE(r,4),o}function ie(e){if(e<=-1||e>9007199254740991)throw Error("Number out of range.");if(Math.floor(e)!==e)throw Error("Number is not an integer.");let o=0,n=e&4294967295,a=n<0?(e&2147483647)+2147483648:n;if(e>4294967295)o=(e-a)/4294967296;return[o,a]}export{v as waitFor,er as uuid,ae as uint53ToLE,ne as uint16ToBE,m as reporter,W as prompt,c as hkdf,V as getMacAddress,M as getLocalIP,R as cli,_ as TimingServer,E as RAOP_SERVICE,z as HTTP_TIMEOUT,l as Discovery,d as Curve25519,u as Chacha20,I as COMPANION_LINK_SERVICE,g as BaseSocket,L as AccessoryVerify,k as AccessoryPair,K as AIRPLAY_TRANSIENT_PIN,w as AIRPLAY_SERVICE};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basmilius/apple-common",
|
|
3
3
|
"description": "Common features shared across various apple protocol packages.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.77",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@basmilius/apple-encoding": "0.0.
|
|
41
|
+
"@basmilius/apple-encoding": "0.0.77",
|
|
42
42
|
"chacha": "^2.1.0",
|
|
43
43
|
"fast-srp-hap": "^2.0.4",
|
|
44
44
|
"node-dns-sd": "^1.0.1",
|