Finished requestPairingCode

This commit is contained in:
Alessandro Autiero
2023-07-16 20:14:17 +02:00
parent f498e1e56c
commit c506182035
8 changed files with 68 additions and 74 deletions

View File

@@ -196,10 +196,11 @@ export const initAuthCreds = (): AuthenticationCreds => {
const identityKey = Curve.generateKeyPair()
return {
noiseKey: Curve.generateKeyPair(),
pairingEphemeralKeyPair: Curve.generateKeyPair(),
signedIdentityKey: identityKey,
signedPreKey: signedKeyPair(identityKey, 1),
registrationId: generateRegistrationId(),
advKeyPair: Curve.generateKeyPair(),
advSecretKey: randomBytes(32).toString('base64'),
processedHistoryMessages: [],
nextPreKeyId: 1,
firstUnuploadedPreKeyId: 1,
@@ -214,6 +215,6 @@ export const initAuthCreds = (): AuthenticationCreds => {
registered: false,
backupToken: randomBytes(20),
registration: {} as never,
pairingCode: undefined
pairingCode: undefined,
}
}

View File

@@ -1,8 +1,8 @@
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from 'crypto'
import {createCipheriv, createDecipheriv, createHash, createHmac, pbkdf2Sync, randomBytes} from 'crypto'
import HKDF from 'futoin-hkdf'
import * as libsignal from 'libsignal'
import { KEY_BUNDLE_TYPE } from '../Defaults'
import { KeyPair } from '../Types'
import {KEY_BUNDLE_TYPE} from '../Defaults'
import {KeyPair} from '../Types'
/** prefix version byte to the pub keys, required for some curve crypto functions */
export const generateSignalPubKey = (pubKey: Uint8Array | Buffer) => (
@@ -74,6 +74,16 @@ export function aesDecryptGCM(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8
return Buffer.concat([ decipher.update(enc), decipher.final() ])
}
export function aesEncryptCTR(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array) {
const cipher = createCipheriv('aes-256-ctr', key, iv)
return Buffer.concat([cipher.update(plaintext), cipher.final()])
}
export function aesDecryptCTR(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array) {
const decipher = createDecipheriv('aes-256-ctr', key, iv)
return Buffer.concat([decipher.update(ciphertext), decipher.final()])
}
/** 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))
@@ -114,4 +124,8 @@ export function md5(buffer: Buffer) {
// HKDF key expansion
export function hkdf(buffer: Uint8Array | Buffer, expandedLength: number, info: { salt?: Buffer, info?: string }) {
return HKDF(!Buffer.isBuffer(buffer) ? Buffer.from(buffer) : buffer, expandedLength, info)
}
export function derivePairingCodeKey(pairingCode: string, salt: Buffer) {
return pbkdf2Sync(pairingCode, salt, 2 << 16, 32, 'sha256')
}

View File

@@ -411,31 +411,4 @@ export function bytesToCrockford(buffer: Buffer): string {
}
return crockford.join('')
}
export async function derivePairingKey(pairingCode: string, salt: Buffer) {
const encoded = new TextEncoder().encode(pairingCode)
const cryptoKey = await crypto.subtle.importKey(
'raw',
encoded,
{
name: 'PBKDF2'
},
!1,
[
'deriveKey'
]
)
return await crypto.subtle.deriveKey({
name: 'PBKDF2',
hash: 'SHA-256',
salt: salt,
iterations: 2 << 16
}, cryptoKey, {
name: 'AES-CTR',
length: 256
}, false, [
'encrypt',
'decrypt'
])
}

View File

@@ -117,7 +117,7 @@ export const generateRegistrationNode = (
export const configureSuccessfulPairing = (
stanza: BinaryNode,
{ advKeyPair, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds, 'advKeyPair' | 'signedIdentityKey' | 'signalIdentities'>
{ advSecretKey, signedIdentityKey, signalIdentities }: Pick<AuthenticationCreds, 'advSecretKey' | 'signedIdentityKey' | 'signalIdentities'>
) => {
const msgId = stanza.attrs.id
@@ -137,7 +137,7 @@ export const configureSuccessfulPairing = (
const { details, hmac } = proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content as Buffer)
// check HMAC matches
const advSign = hmacSign(details, advKeyPair.public)
const advSign = hmacSign(details, Buffer.from(advSecretKey, 'base64'))
if(Buffer.compare(hmac, advSign) !== 0) {
throw new Boom('Invalid account signature')
}
@@ -208,8 +208,7 @@ export const encodeSignedDeviceIdentity = (
account.accountSignatureKey = null
}
const accountEnc = proto.ADVSignedDeviceIdentity
return proto.ADVSignedDeviceIdentity
.encode(account)
.finish()
return accountEnc
}