Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/node_modules/@adiwajshing/baileys/lib/Utils/noise-handler.js
1129 views
1
"use strict";
2
Object.defineProperty(exports, "__esModule", { value: true });
3
exports.makeNoiseHandler = void 0;
4
const boom_1 = require("@hapi/boom");
5
const WAProto_1 = require("../../WAProto");
6
const Defaults_1 = require("../Defaults");
7
const WABinary_1 = require("../WABinary");
8
const crypto_1 = require("./crypto");
9
const generateIV = (counter) => {
10
const iv = new ArrayBuffer(12);
11
new DataView(iv).setUint32(8, counter);
12
return new Uint8Array(iv);
13
};
14
const makeNoiseHandler = ({ public: publicKey, private: privateKey }, logger) => {
15
logger = logger.child({ class: 'ns' });
16
const authenticate = (data) => {
17
if (!isFinished) {
18
hash = (0, crypto_1.sha256)(Buffer.concat([hash, data]));
19
}
20
};
21
const encrypt = (plaintext) => {
22
const result = (0, crypto_1.aesEncryptGCM)(plaintext, encKey, generateIV(writeCounter), hash);
23
writeCounter += 1;
24
authenticate(result);
25
return result;
26
};
27
const decrypt = (ciphertext) => {
28
// before the handshake is finished, we use the same counter
29
// after handshake, the counters are different
30
const iv = generateIV(isFinished ? readCounter : writeCounter);
31
const result = (0, crypto_1.aesDecryptGCM)(ciphertext, decKey, iv, hash);
32
if (isFinished) {
33
readCounter += 1;
34
}
35
else {
36
writeCounter += 1;
37
}
38
authenticate(ciphertext);
39
return result;
40
};
41
const localHKDF = (data) => {
42
const key = (0, crypto_1.hkdf)(Buffer.from(data), 64, { salt, info: '' });
43
return [key.slice(0, 32), key.slice(32)];
44
};
45
const mixIntoKey = (data) => {
46
const [write, read] = localHKDF(data);
47
salt = write;
48
encKey = read;
49
decKey = read;
50
readCounter = 0;
51
writeCounter = 0;
52
};
53
const finishInit = () => {
54
const [write, read] = localHKDF(new Uint8Array(0));
55
encKey = write;
56
decKey = read;
57
hash = Buffer.from([]);
58
readCounter = 0;
59
writeCounter = 0;
60
isFinished = true;
61
};
62
const data = Buffer.from(Defaults_1.NOISE_MODE);
63
let hash = Buffer.from(data.byteLength === 32 ? data : (0, crypto_1.sha256)(Buffer.from(data)));
64
let salt = hash;
65
let encKey = hash;
66
let decKey = hash;
67
let readCounter = 0;
68
let writeCounter = 0;
69
let isFinished = false;
70
let sentIntro = false;
71
let inBytes = Buffer.alloc(0);
72
authenticate(Defaults_1.NOISE_WA_HEADER);
73
authenticate(publicKey);
74
return {
75
encrypt,
76
decrypt,
77
authenticate,
78
mixIntoKey,
79
finishInit,
80
processHandshake: ({ serverHello }, noiseKey) => {
81
authenticate(serverHello.ephemeral);
82
mixIntoKey(crypto_1.Curve.sharedKey(privateKey, serverHello.ephemeral));
83
const decStaticContent = decrypt(serverHello.static);
84
mixIntoKey(crypto_1.Curve.sharedKey(privateKey, decStaticContent));
85
const certDecoded = decrypt(serverHello.payload);
86
const { intermediate: certIntermediate } = WAProto_1.proto.CertChain.decode(certDecoded);
87
const { issuerSerial } = WAProto_1.proto.CertChain.NoiseCertificate.Details.decode(certIntermediate.details);
88
if (issuerSerial !== Defaults_1.WA_CERT_DETAILS.SERIAL) {
89
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
90
}
91
const keyEnc = encrypt(noiseKey.public);
92
mixIntoKey(crypto_1.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
93
return keyEnc;
94
},
95
encodeFrame: (data) => {
96
if (isFinished) {
97
data = encrypt(data);
98
}
99
const introSize = sentIntro ? 0 : Defaults_1.NOISE_WA_HEADER.length;
100
const frame = Buffer.alloc(introSize + 3 + data.byteLength);
101
if (!sentIntro) {
102
frame.set(Defaults_1.NOISE_WA_HEADER);
103
sentIntro = true;
104
}
105
frame.writeUInt8(data.byteLength >> 16, introSize);
106
frame.writeUInt16BE(65535 & data.byteLength, introSize + 1);
107
frame.set(data, introSize + 3);
108
return frame;
109
},
110
decodeFrame: (newData, onFrame) => {
111
var _a;
112
// the binary protocol uses its own framing mechanism
113
// on top of the WS frames
114
// so we get this data and separate out the frames
115
const getBytesSize = () => {
116
if (inBytes.length >= 3) {
117
return (inBytes.readUInt8() << 16) | inBytes.readUInt16BE(1);
118
}
119
};
120
inBytes = Buffer.concat([inBytes, newData]);
121
logger.trace(`recv ${newData.length} bytes, total recv ${inBytes.length} bytes`);
122
let size = getBytesSize();
123
while (size && inBytes.length >= size + 3) {
124
let frame = inBytes.slice(3, size + 3);
125
inBytes = inBytes.slice(size + 3);
126
if (isFinished) {
127
const result = decrypt(frame);
128
frame = (0, WABinary_1.decodeBinaryNode)(result);
129
}
130
logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
131
onFrame(frame);
132
size = getBytesSize();
133
}
134
}
135
};
136
};
137
exports.makeNoiseHandler = makeNoiseHandler;
138
139