Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jajbshjahavahh
GitHub Repository: jajbshjahavahh/Gojo-Satoru
Path: blob/master/node_modules/@adiwajshing/baileys/lib/Utils/noise-handler.js
2593 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 crypto_1 = require("crypto");
6
const WAProto_1 = require("../../WAProto");
7
const Defaults_1 = require("../Defaults");
8
const WABinary_1 = require("../WABinary");
9
const WABinary_2 = require("../WABinary");
10
const crypto_2 = require("./crypto");
11
const generateIV = (counter) => {
12
const iv = new ArrayBuffer(12);
13
new DataView(iv).setUint32(8, counter);
14
return new Uint8Array(iv);
15
};
16
const makeNoiseHandler = ({ public: publicKey, private: privateKey }) => {
17
const authenticate = (data) => {
18
if (!isFinished) {
19
hash = crypto_2.sha256(Buffer.from(WABinary_1.Binary.build(hash, data).readByteArray()));
20
}
21
};
22
const encrypt = (plaintext) => {
23
const authTagLength = 128 >> 3;
24
const cipher = crypto_1.createCipheriv('aes-256-gcm', encKey, generateIV(writeCounter), { authTagLength });
25
cipher.setAAD(hash);
26
const result = Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);
27
writeCounter += 1;
28
authenticate(result);
29
return result;
30
};
31
const decrypt = (ciphertext) => {
32
// before the handshake is finished, we use the same counter
33
// after handshake, the counters are different
34
const iv = generateIV(isFinished ? readCounter : writeCounter);
35
const cipher = crypto_1.createDecipheriv('aes-256-gcm', decKey, iv);
36
// decrypt additional adata
37
const tagLength = 128 >> 3;
38
const enc = ciphertext.slice(0, ciphertext.length - tagLength);
39
const tag = ciphertext.slice(ciphertext.length - tagLength);
40
// set additional data
41
cipher.setAAD(hash);
42
cipher.setAuthTag(tag);
43
const result = Buffer.concat([cipher.update(enc), cipher.final()]);
44
if (isFinished) {
45
readCounter += 1;
46
}
47
else {
48
writeCounter += 1;
49
}
50
authenticate(ciphertext);
51
return result;
52
};
53
const localHKDF = (data) => {
54
const key = crypto_2.hkdf(Buffer.from(data), 64, { salt, info: '' });
55
return [key.slice(0, 32), key.slice(32)];
56
};
57
const mixIntoKey = (data) => {
58
const [write, read] = localHKDF(data);
59
salt = write;
60
encKey = read;
61
decKey = read;
62
readCounter = 0;
63
writeCounter = 0;
64
};
65
const finishInit = () => {
66
const [write, read] = localHKDF(new Uint8Array(0));
67
encKey = write;
68
decKey = read;
69
hash = Buffer.from([]);
70
readCounter = 0;
71
writeCounter = 0;
72
isFinished = true;
73
};
74
const data = WABinary_1.Binary.build(Defaults_1.NOISE_MODE).readBuffer();
75
let hash = Buffer.from(data.byteLength === 32 ? data : crypto_2.sha256(Buffer.from(data)));
76
let salt = hash;
77
let encKey = hash;
78
let decKey = hash;
79
let readCounter = 0;
80
let writeCounter = 0;
81
let isFinished = false;
82
let sentIntro = false;
83
const outBinary = new WABinary_1.Binary();
84
const inBinary = new WABinary_1.Binary();
85
authenticate(Defaults_1.NOISE_WA_HEADER);
86
authenticate(publicKey);
87
return {
88
encrypt,
89
decrypt,
90
authenticate,
91
mixIntoKey,
92
finishInit,
93
processHandshake: ({ serverHello }, noiseKey) => {
94
authenticate(serverHello.ephemeral);
95
mixIntoKey(crypto_2.Curve.sharedKey(privateKey, serverHello.ephemeral));
96
const decStaticContent = decrypt(serverHello.static);
97
mixIntoKey(crypto_2.Curve.sharedKey(privateKey, decStaticContent));
98
const certDecoded = decrypt(serverHello.payload);
99
const { details: certDetails, signature: certSignature } = WAProto_1.proto.NoiseCertificate.decode(certDecoded);
100
const { key: certKey } = WAProto_1.proto.NoiseCertificateDetails.decode(certDetails);
101
if (Buffer.compare(decStaticContent, certKey) !== 0) {
102
throw new boom_1.Boom('certification match failed', { statusCode: 400 });
103
}
104
const keyEnc = encrypt(noiseKey.public);
105
mixIntoKey(crypto_2.Curve.sharedKey(noiseKey.private, serverHello.ephemeral));
106
return keyEnc;
107
},
108
encodeFrame: (data) => {
109
if (isFinished) {
110
data = encrypt(data);
111
}
112
const introSize = sentIntro ? 0 : Defaults_1.NOISE_WA_HEADER.length;
113
outBinary.ensureAdditionalCapacity(introSize + 3 + data.byteLength);
114
if (!sentIntro) {
115
outBinary.writeByteArray(Defaults_1.NOISE_WA_HEADER);
116
sentIntro = true;
117
}
118
outBinary.writeUint8(data.byteLength >> 16);
119
outBinary.writeUint16(65535 & data.byteLength);
120
outBinary.write(data);
121
const bytes = outBinary.readByteArray();
122
return bytes;
123
},
124
decodeFrame: (newData, onFrame) => {
125
// the binary protocol uses its own framing mechanism
126
// on top of the WS frames
127
// so we get this data and separate out the frames
128
const getBytesSize = () => {
129
return (inBinary.readUint8() << 16) | inBinary.readUint16();
130
};
131
const peekSize = () => {
132
return !(inBinary.size() < 3) && getBytesSize() <= inBinary.size();
133
};
134
inBinary.writeByteArray(newData);
135
while (inBinary.peek(peekSize)) {
136
const bytes = getBytesSize();
137
let frame = inBinary.readByteArray(bytes);
138
if (isFinished) {
139
const result = decrypt(frame);
140
const unpacked = new WABinary_1.Binary(result).decompressed();
141
frame = WABinary_2.decodeBinaryNode(unpacked);
142
}
143
onFrame(frame);
144
}
145
inBinary.peek(peekSize);
146
}
147
};
148
};
149
exports.makeNoiseHandler = makeNoiseHandler;
150
151