Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/node_modules/@adiwajshing/baileys/WASignalGroup/group_cipher.js
1126 views
1
const SenderKeyMessage = require('./sender_key_message');
2
const crypto = require('libsignal/src/crypto');
3
4
class GroupCipher {
5
constructor(senderKeyStore, senderKeyName) {
6
this.senderKeyStore = senderKeyStore;
7
this.senderKeyName = senderKeyName;
8
}
9
10
async encrypt(paddedPlaintext) {
11
try {
12
const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);
13
const senderKeyState = record.getSenderKeyState();
14
const senderKey = senderKeyState.getSenderChainKey().getSenderMessageKey();
15
16
const ciphertext = await this.getCipherText(
17
senderKey.getIv(),
18
senderKey.getCipherKey(),
19
paddedPlaintext
20
);
21
22
const senderKeyMessage = new SenderKeyMessage(
23
senderKeyState.getKeyId(),
24
senderKey.getIteration(),
25
ciphertext,
26
senderKeyState.getSigningKeyPrivate()
27
);
28
senderKeyState.setSenderChainKey(senderKeyState.getSenderChainKey().getNext());
29
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
30
return senderKeyMessage.serialize();
31
} catch (e) {
32
//console.log(e.stack);
33
throw new Error('NoSessionException');
34
}
35
}
36
37
async decrypt(senderKeyMessageBytes) {
38
const record = await this.senderKeyStore.loadSenderKey(this.senderKeyName);
39
if (!record) throw new Error(`No sender key for: ${this.senderKeyName}`);
40
41
const senderKeyMessage = new SenderKeyMessage(null, null, null, null, senderKeyMessageBytes);
42
43
const senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
44
//senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
45
const senderKey = this.getSenderKey(senderKeyState, senderKeyMessage.getIteration());
46
// senderKeyState.senderKeyStateStructure.senderSigningKey.private =
47
48
const plaintext = await this.getPlainText(
49
senderKey.getIv(),
50
senderKey.getCipherKey(),
51
senderKeyMessage.getCipherText()
52
);
53
54
await this.senderKeyStore.storeSenderKey(this.senderKeyName, record);
55
56
return plaintext;
57
}
58
59
getSenderKey(senderKeyState, iteration) {
60
let senderChainKey = senderKeyState.getSenderChainKey();
61
if (senderChainKey.getIteration() > iteration) {
62
if (senderKeyState.hasSenderMessageKey(iteration)) {
63
return senderKeyState.removeSenderMessageKey(iteration);
64
}
65
throw new Error(
66
`Received message with old counter: ${senderChainKey.getIteration()}, ${iteration}`
67
);
68
}
69
70
if (senderChainKey.getIteration() - iteration > 2000) {
71
throw new Error('Over 2000 messages into the future!');
72
}
73
74
while (senderChainKey.getIteration() < iteration) {
75
senderKeyState.addSenderMessageKey(senderChainKey.getSenderMessageKey());
76
senderChainKey = senderChainKey.getNext();
77
}
78
79
senderKeyState.setSenderChainKey(senderChainKey.getNext());
80
return senderChainKey.getSenderMessageKey();
81
}
82
83
getPlainText(iv, key, ciphertext) {
84
try {
85
const plaintext = crypto.decrypt(key, ciphertext, iv);
86
return plaintext;
87
} catch (e) {
88
//console.log(e.stack);
89
throw new Error('InvalidMessageException');
90
}
91
}
92
93
getCipherText(iv, key, plaintext) {
94
try {
95
iv = typeof iv === 'string' ? Buffer.from(iv, 'base64') : iv;
96
key = typeof key === 'string' ? Buffer.from(key, 'base64') : key;
97
const crypted = crypto.encrypt(key, Buffer.from(plaintext), iv);
98
return crypted;
99
} catch (e) {
100
//console.log(e.stack);
101
throw new Error('InvalidMessageException');
102
}
103
}
104
}
105
106
module.exports = GroupCipher;
107