mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
separate out crypto utils
This commit is contained in:
@@ -78,9 +78,10 @@ If the connection is successful, you will see a QR code printed on your terminal
|
||||
|
||||
## Notable Differences Between Baileys Web & MD
|
||||
|
||||
1. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this.
|
||||
2. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations.
|
||||
3. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script)
|
||||
1. Baileys has been written from the ground up to have a more "functional" structure. This is done primarily for simplicity & more testability
|
||||
2. Baileys no longer maintains an internal state of chats/contacts/messages. You must take this on your own, simply because your state in MD is its own source of truth & there is no one-size-fits-all way to handle the storage for this.
|
||||
3. A baileys "socket" is meant to be a temporary & disposable object -- this is done to maintain simplicity & prevent bugs. I felt the entire Baileys object became too bloated as it supported too many configurations. You're encouraged to write your own implementation to handle missing functionality.
|
||||
4. Moreover, Baileys does not offer an inbuilt reconnect mechanism anymore (though it's super easy to set one up on your own with your own rules, check the example script)
|
||||
|
||||
## Configuring the Connection
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, jidNormalizedUse
|
||||
import { makeSocket } from "./socket";
|
||||
import { proto } from '../../WAProto'
|
||||
import { toNumber } from "../Utils/generics";
|
||||
import { compressImage, generateProfilePicture } from "..";
|
||||
import { generateProfilePicture } from "../Utils";
|
||||
|
||||
export const makeChatsSocket = (config: SocketConfig) => {
|
||||
const { logger } = config
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import { makeGroupsSocket } from "./groups"
|
||||
import { SocketConfig, WAMessageStubType, ParticipantAction, Chat, GroupMetadata } from "../Types"
|
||||
import { decodeMessageStanza, encodeBigEndian, toNumber, whatsappID } from "../Utils"
|
||||
import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, S_WHATSAPP_NET, areJidsSameUser, getBinaryNodeChildren, getBinaryNodeChild } from '../WABinary'
|
||||
import { decodeMessageStanza, encodeBigEndian, toNumber } from "../Utils"
|
||||
import { BinaryNode, jidDecode, jidEncode, isJidStatusBroadcast, areJidsSameUser, getBinaryNodeChildren } from '../WABinary'
|
||||
import { downloadIfHistory } from '../Utils/history'
|
||||
import { proto } from "../../WAProto"
|
||||
import { generateSignalPubKey, xmppPreKey, xmppSignedPreKey } from "../Utils/signal"
|
||||
@@ -139,7 +139,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
switch (message.messageStubType) {
|
||||
case WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
||||
case WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
||||
participants = message.messageStubParameters.map(whatsappID)
|
||||
participants = message.messageStubParameters
|
||||
emitParticipantsUpdate('remove')
|
||||
// mark the chat read only if you left the group
|
||||
if (participants.includes(meJid)) {
|
||||
@@ -149,7 +149,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
case WAMessageStubType.GROUP_PARTICIPANT_ADD:
|
||||
case WAMessageStubType.GROUP_PARTICIPANT_INVITE:
|
||||
case WAMessageStubType.GROUP_PARTICIPANT_ADD_REQUEST_JOIN:
|
||||
participants = message.messageStubParameters.map(whatsappID)
|
||||
participants = message.messageStubParameters
|
||||
if (participants.includes(meJid)) {
|
||||
chatUpdate.readOnly = false
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import WebSocket from "ws"
|
||||
import { randomBytes } from 'crypto'
|
||||
import { proto } from '../../WAProto'
|
||||
import { DisconnectReason, SocketConfig, BaileysEventEmitter } from "../Types"
|
||||
import { generateCurveKeyPair, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils"
|
||||
import { Curve, initAuthState, generateRegistrationNode, configureSuccessfulPairing, generateLoginNode, encodeBigEndian, promiseTimeout } from "../Utils"
|
||||
import { DEFAULT_ORIGIN, DEF_TAG_PREFIX, DEF_CALLBACK_PREFIX, KEY_BUNDLE_TYPE } from "../Defaults"
|
||||
import { assertNodeErrorFree, BinaryNode, encodeBinaryNode, S_WHATSAPP_NET } from '../WABinary'
|
||||
import noiseHandler from '../Utils/noise-handler'
|
||||
@@ -42,7 +42,7 @@ export const makeSocket = ({
|
||||
})
|
||||
ws.setMaxListeners(0)
|
||||
/** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
|
||||
const ephemeralKeyPair = generateCurveKeyPair()
|
||||
const ephemeralKeyPair = Curve.generateKeyPair()
|
||||
/** WA noise protocol wrapper */
|
||||
const noise = noiseHandler(ephemeralKeyPair)
|
||||
const authState = initialAuthState || initAuthState()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./generics"
|
||||
import { aesDecrypt, hmacSign, aesEncrypt, hkdf } from "./crypto"
|
||||
import { AuthenticationState, ChatModification } from "../Types"
|
||||
import { proto } from '../../WAProto'
|
||||
import { LT_HASH_ANTI_TAMPERING } from '../WABinary/LTHash'
|
||||
|
||||
100
src/Utils/crypto.ts
Normal file
100
src/Utils/crypto.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
import CurveCrypto from 'libsignal/src/curve25519_wrapper'
|
||||
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto'
|
||||
import { KeyPair } from '../Types'
|
||||
|
||||
export const Curve = {
|
||||
generateKeyPair: (): KeyPair => {
|
||||
const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32))
|
||||
return {
|
||||
private: Buffer.from(privKey),
|
||||
public: Buffer.from(pubKey)
|
||||
}
|
||||
},
|
||||
sharedKey: (privateKey: Uint8Array, publicKey: Uint8Array) => {
|
||||
const shared = CurveCrypto.sharedSecret(publicKey, privateKey)
|
||||
return Buffer.from(shared)
|
||||
},
|
||||
sign: (privateKey: Uint8Array, buf: Uint8Array) => (
|
||||
Buffer.from(CurveCrypto.sign(privateKey, buf))
|
||||
),
|
||||
verify: (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => {
|
||||
try {
|
||||
CurveCrypto.verify(pubKey, message, signature)
|
||||
return true
|
||||
} catch(error) {
|
||||
if(error.message.includes('Invalid')) {
|
||||
return false
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const signedKeyPair = (keyPair: KeyPair, keyId: number) => {
|
||||
const signKeys = Curve.generateKeyPair()
|
||||
const pubKey = new Uint8Array(33)
|
||||
pubKey.set([5], 0)
|
||||
pubKey.set(signKeys.public, 1)
|
||||
|
||||
const signature = Curve.sign(keyPair.private, pubKey)
|
||||
|
||||
return { keyPair: signKeys, signature, keyId }
|
||||
}
|
||||
|
||||
/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
|
||||
export function aesDecrypt(buffer: Buffer, key: Buffer) {
|
||||
return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16))
|
||||
}
|
||||
/** decrypt AES 256 CBC */
|
||||
export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) {
|
||||
const aes = createDecipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([aes.update(buffer), aes.final()])
|
||||
}
|
||||
// encrypt AES 256 CBC; where a random IV is prefixed to the buffer
|
||||
export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) {
|
||||
const IV = randomBytes(16)
|
||||
const aes = createCipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer
|
||||
}
|
||||
// encrypt AES 256 CBC with a given IV
|
||||
export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) {
|
||||
const aes = createCipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer
|
||||
}
|
||||
// sign HMAC using SHA 256
|
||||
export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') {
|
||||
return createHmac(variant, key).update(buffer).digest()
|
||||
}
|
||||
export function sha256(buffer: Buffer) {
|
||||
return createHash('sha256').update(buffer).digest()
|
||||
}
|
||||
// HKDF key expansion
|
||||
// from: https://github.com/benadida/node-hkdf
|
||||
export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) {
|
||||
const hashAlg = 'sha256'
|
||||
const hashLength = 32
|
||||
salt = salt || Buffer.alloc(hashLength)
|
||||
// now we compute the PRK
|
||||
const prk = createHmac(hashAlg, salt).update(buffer).digest()
|
||||
|
||||
let prev = Buffer.from([])
|
||||
const buffers = []
|
||||
const num_blocks = Math.ceil(expandedLength / hashLength)
|
||||
|
||||
const infoBuff = Buffer.from(info || [])
|
||||
|
||||
for (var i=0; i<num_blocks; i++) {
|
||||
const hmac = createHmac(hashAlg, prk)
|
||||
// XXX is there a more optimal way to build up buffers?
|
||||
const input = Buffer.concat([
|
||||
prev,
|
||||
infoBuff,
|
||||
Buffer.from(String.fromCharCode(i + 1))
|
||||
]);
|
||||
hmac.update(input)
|
||||
|
||||
prev = hmac.digest()
|
||||
buffers.push(prev)
|
||||
}
|
||||
return Buffer.concat(buffers, expandedLength)
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Boom } from '@hapi/boom'
|
||||
import CurveCrypto from 'libsignal/src/curve25519_wrapper'
|
||||
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto'
|
||||
import { randomBytes } from 'crypto'
|
||||
import { platform, release } from 'os'
|
||||
import { KeyPair } from '../Types'
|
||||
import { proto } from '../../WAProto'
|
||||
import { Binary } from '../WABinary'
|
||||
|
||||
@@ -71,46 +69,6 @@ export const encodeWAMessage = (message: proto.IMessage) => (
|
||||
)
|
||||
)
|
||||
|
||||
export const generateCurveKeyPair = (): KeyPair => {
|
||||
const { pubKey, privKey } = CurveCrypto.keyPair(randomBytes(32))
|
||||
return {
|
||||
private: Buffer.from(privKey),
|
||||
public: Buffer.from(pubKey)
|
||||
}
|
||||
}
|
||||
|
||||
export const generateSharedKey = (privateKey: Uint8Array, publicKey: Uint8Array) => {
|
||||
const shared = CurveCrypto.sharedSecret(publicKey, privateKey)
|
||||
return Buffer.from(shared)
|
||||
}
|
||||
|
||||
export const curveSign = (privateKey: Uint8Array, buf: Uint8Array) => (
|
||||
Buffer.from(CurveCrypto.sign(privateKey, buf))
|
||||
)
|
||||
|
||||
export const curveVerify = (pubKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => {
|
||||
try {
|
||||
CurveCrypto.verify(pubKey, message, signature)
|
||||
return true
|
||||
} catch(error) {
|
||||
if(error.message.includes('Invalid')) {
|
||||
return false
|
||||
}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export const signedKeyPair = (keyPair: KeyPair, keyId: number) => {
|
||||
const signKeys = generateCurveKeyPair()
|
||||
const pubKey = new Uint8Array(33)
|
||||
pubKey.set([5], 0)
|
||||
pubKey.set(signKeys.public, 1)
|
||||
|
||||
const signature = curveSign(keyPair.private, pubKey)
|
||||
|
||||
return { keyPair: signKeys, signature, keyId }
|
||||
}
|
||||
|
||||
export const generateRegistrationId = () => (
|
||||
Uint16Array.from(randomBytes(2))[0] & 0x3fff
|
||||
)
|
||||
@@ -134,9 +92,6 @@ export const encodeBigEndian = (e: number, t=4) => {
|
||||
|
||||
export const toNumber = (t: Long | number) => (typeof t?.['low'] !== 'undefined' ? t['low'] : t) as number
|
||||
|
||||
export const whatsappID = (jid: string) => jid?.replace ('@c.us', '@s.whatsapp.net')
|
||||
export const isGroupID = (jid: string) => jid?.endsWith ('@g.us')
|
||||
|
||||
export function shallowChanges <T> (old: T, current: T, {lookForDeletedKeys}: {lookForDeletedKeys: boolean}): Partial<T> {
|
||||
let changes: Partial<T> = {}
|
||||
for (let key in current) {
|
||||
@@ -153,64 +108,6 @@ export function shallowChanges <T> (old: T, current: T, {lookForDeletedKeys}: {l
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
/** decrypt AES 256 CBC; where the IV is prefixed to the buffer */
|
||||
export function aesDecrypt(buffer: Buffer, key: Buffer) {
|
||||
return aesDecryptWithIV(buffer.slice(16, buffer.length), key, buffer.slice(0, 16))
|
||||
}
|
||||
/** decrypt AES 256 CBC */
|
||||
export function aesDecryptWithIV(buffer: Buffer, key: Buffer, IV: Buffer) {
|
||||
const aes = createDecipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([aes.update(buffer), aes.final()])
|
||||
}
|
||||
// encrypt AES 256 CBC; where a random IV is prefixed to the buffer
|
||||
export function aesEncrypt(buffer: Buffer | Uint8Array, key: Buffer) {
|
||||
const IV = randomBytes(16)
|
||||
const aes = createCipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([IV, aes.update(buffer), aes.final()]) // prefix IV to the buffer
|
||||
}
|
||||
// encrypt AES 256 CBC with a given IV
|
||||
export function aesEncrypWithIV(buffer: Buffer, key: Buffer, IV: Buffer) {
|
||||
const aes = createCipheriv('aes-256-cbc', key, IV)
|
||||
return Buffer.concat([aes.update(buffer), aes.final()]) // prefix IV to the buffer
|
||||
}
|
||||
// sign HMAC using SHA 256
|
||||
export function hmacSign(buffer: Buffer | Uint8Array, key: Buffer | Uint8Array, variant: 'sha256' | 'sha512' = 'sha256') {
|
||||
return createHmac(variant, key).update(buffer).digest()
|
||||
}
|
||||
export function sha256(buffer: Buffer) {
|
||||
return createHash('sha256').update(buffer).digest()
|
||||
}
|
||||
// HKDF key expansion
|
||||
// from: https://github.com/benadida/node-hkdf
|
||||
export function hkdf(buffer: Buffer, expandedLength: number, { info, salt }: { salt?: Buffer, info?: string }) {
|
||||
const hashAlg = 'sha256'
|
||||
const hashLength = 32
|
||||
salt = salt || Buffer.alloc(hashLength)
|
||||
// now we compute the PRK
|
||||
const prk = createHmac(hashAlg, salt).update(buffer).digest()
|
||||
|
||||
let prev = Buffer.from([])
|
||||
const buffers = []
|
||||
const num_blocks = Math.ceil(expandedLength / hashLength)
|
||||
|
||||
const infoBuff = Buffer.from(info || [])
|
||||
|
||||
for (var i=0; i<num_blocks; i++) {
|
||||
const hmac = createHmac(hashAlg, prk)
|
||||
// XXX is there a more optimal way to build up buffers?
|
||||
const input = Buffer.concat([
|
||||
prev,
|
||||
infoBuff,
|
||||
Buffer.from(String.fromCharCode(i + 1))
|
||||
]);
|
||||
hmac.update(input)
|
||||
|
||||
prev = hmac.digest()
|
||||
buffers.push(prev)
|
||||
}
|
||||
return Buffer.concat(buffers, expandedLength)
|
||||
}
|
||||
/** unix timestamp of a date in seconds */
|
||||
export const unixTimestampSeconds = (date: Date = new Date()) => Math.floor(date.getTime()/1000)
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ export * from './decode-wa-message'
|
||||
export * from './generics'
|
||||
export * from './messages'
|
||||
export * from './messages-media'
|
||||
export * from './validate-connection'
|
||||
export * from './validate-connection'
|
||||
export * from './crypto'
|
||||
@@ -11,7 +11,8 @@ import { join } from 'path'
|
||||
import { once } from 'events'
|
||||
import got, { Options, Response } from 'got'
|
||||
import { MessageType, WAMessageContent, WAProto, WAGenericMediaMessage, WAMediaUpload, MediaType } from '../Types'
|
||||
import { generateMessageID, hkdf } from './generics'
|
||||
import { generateMessageID } from './generics'
|
||||
import { hkdf } from './crypto'
|
||||
import { DEFAULT_ORIGIN } from '../Defaults'
|
||||
|
||||
export const hkdfInfoKey = (type: MediaType) => {
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
MediaType,
|
||||
WAMessageStatus
|
||||
} from "../Types"
|
||||
import { generateMessageID, unixTimestampSeconds, whatsappID } from "./generics"
|
||||
import { generateMessageID, unixTimestampSeconds } from "./generics"
|
||||
import { encryptedStream, generateThumbnail, getAudioDuration } from "./messages-media"
|
||||
|
||||
type MediaUploadData = {
|
||||
@@ -268,8 +268,6 @@ export const generateWAMessageFromContent = (
|
||||
options: MessageGenerationOptionsFromContent
|
||||
) => {
|
||||
if (!options.timestamp) options.timestamp = new Date() // set timestamp to now
|
||||
// prevent an annoying bug (WA doesn't accept sending messages with '@c.us')
|
||||
jid = whatsappID(jid)
|
||||
|
||||
const key = Object.keys(message)[0]
|
||||
const timestamp = unixTimestampSeconds(options.timestamp)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sha256, generateSharedKey, hkdf } from "./generics";
|
||||
import { sha256, Curve, hkdf } from "./crypto";
|
||||
import { Binary } from "../WABinary";
|
||||
import { createCipheriv, createDecipheriv } from "crypto";
|
||||
import { NOISE_MODE, NOISE_WA_HEADER } from "../Defaults";
|
||||
@@ -100,10 +100,10 @@ export default ({ public: publicKey, private: privateKey }: KeyPair) => {
|
||||
finishInit,
|
||||
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => {
|
||||
authenticate(serverHello!.ephemeral!)
|
||||
mixIntoKey(generateSharedKey(privateKey, serverHello.ephemeral!))
|
||||
mixIntoKey(Curve.sharedKey(privateKey, serverHello.ephemeral!))
|
||||
|
||||
const decStaticContent = decrypt(serverHello!.static!)
|
||||
mixIntoKey(generateSharedKey(privateKey, decStaticContent))
|
||||
mixIntoKey(Curve.sharedKey(privateKey, decStaticContent))
|
||||
|
||||
const certDecoded = decrypt(serverHello!.payload!)
|
||||
const { details: certDetails, signature: certSignature } = proto.NoiseCertificate.decode(certDecoded)
|
||||
@@ -115,7 +115,7 @@ export default ({ public: publicKey, private: privateKey }: KeyPair) => {
|
||||
}
|
||||
|
||||
const keyEnc = encrypt(noiseKey.public)
|
||||
mixIntoKey(generateSharedKey(noiseKey.private, serverHello!.ephemeral!))
|
||||
mixIntoKey(Curve.sharedKey(noiseKey.private, serverHello!.ephemeral!))
|
||||
|
||||
return keyEnc
|
||||
},
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as libsignal from 'libsignal'
|
||||
import { encodeBigEndian, generateCurveKeyPair } from "./generics"
|
||||
import { encodeBigEndian } from "./generics"
|
||||
import { Curve } from "./crypto"
|
||||
import { SenderKeyDistributionMessage, GroupSessionBuilder, SenderKeyRecord, SenderKeyName, GroupCipher } from '../../WASignalGroup'
|
||||
import { SignalIdentity, SignalKeyStore, SignedKeyPair, KeyPair, AuthenticationState } from "../Types/Auth"
|
||||
import { assertNodeErrorFree, BinaryNode, getBinaryNodeChild, getBinaryNodeChildBuffer, getBinaryNodeChildUInt, jidDecode } from "../WABinary"
|
||||
@@ -48,7 +49,7 @@ export const generateOrGetPreKeys = ({ creds }: AuthenticationState, range: numb
|
||||
const newPreKeys: { [id: number]: KeyPair } = { }
|
||||
if(remaining > 0) {
|
||||
for(let i = creds.nextPreKeyId;i <= lastPreKeyId;i++) {
|
||||
newPreKeys[i] = generateCurveKeyPair()
|
||||
newPreKeys[i] = Curve.generateKeyPair()
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -2,7 +2,8 @@ import { Boom } from '@hapi/boom'
|
||||
import { randomBytes } from 'crypto'
|
||||
import { proto } from '../../WAProto'
|
||||
import type { AuthenticationState, SocketConfig, SignalKeyStore, AuthenticationCreds, KeyPair } from "../Types"
|
||||
import { curveSign, hmacSign, curveVerify, encodeInt, generateCurveKeyPair, generateRegistrationId, signedKeyPair } from './generics'
|
||||
import { Curve, hmacSign, signedKeyPair } from './crypto'
|
||||
import { encodeInt, generateRegistrationId } from './generics'
|
||||
import { BinaryNode, S_WHATSAPP_NET, jidDecode, Binary } from '../WABinary'
|
||||
import { createSignalIdentity } from './signal'
|
||||
|
||||
@@ -116,10 +117,10 @@ export const initInMemoryKeyStore = (
|
||||
}
|
||||
|
||||
export const initAuthState = (): AuthenticationState => {
|
||||
const identityKey = generateCurveKeyPair()
|
||||
const identityKey = Curve.generateKeyPair()
|
||||
return {
|
||||
creds: {
|
||||
noiseKey: generateCurveKeyPair(),
|
||||
noiseKey: Curve.generateKeyPair(),
|
||||
signedIdentityKey: identityKey,
|
||||
signedPreKey: signedKeyPair(identityKey, 1),
|
||||
registrationId: generateRegistrationId(),
|
||||
@@ -158,12 +159,12 @@ export const configureSuccessfulPairing = (
|
||||
const { accountSignatureKey, accountSignature } = account
|
||||
|
||||
const accountMsg = Binary.build(new Uint8Array([6, 0]), account.details, signedIdentityKey.public).readByteArray()
|
||||
if (!curveVerify(accountSignatureKey, accountMsg, accountSignature)) {
|
||||
if (!Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
||||
throw new Boom('Failed to verify account signature')
|
||||
}
|
||||
|
||||
const deviceMsg = Binary.build(new Uint8Array([6, 1]), account.details, signedIdentityKey.public, account.accountSignatureKey).readByteArray()
|
||||
account.deviceSignature = curveSign(signedIdentityKey.private, deviceMsg)
|
||||
account.deviceSignature = Curve.sign(signedIdentityKey.private, deviceMsg)
|
||||
|
||||
const identity = createSignalIdentity(jid, accountSignatureKey)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user