// Copyright 2022 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { promisify } from 'util'; import { SignalService as Proto } from '../protobuf'; import { calculateAgreement, generateKeyPair } from '../Curve'; import { encryptAttachment, deriveSecrets } from '../Crypto'; import * as Bytes from '../Bytes'; const PROVISIONING_INFO = 'Art Service Provisioning Message'; export type AuthorizeArtCreatorOptionsType = Readonly<{ token: string; pubKeyBase64: string; }>; export async function authorizeArtCreator({ token, pubKeyBase64: theirPubKeyBase64, }: AuthorizeArtCreatorOptionsType): Promise { const { server } = window.textsecure; if (!server) { throw new Error('Server not ready'); } const auth = await server.getArtAuth(); const ourKeys = generateKeyPair(); const theirPubKey = Bytes.fromBase64(theirPubKeyBase64); const secret = calculateAgreement(theirPubKey, ourKeys.privKey); const [aesKey, macKey] = deriveSecrets( secret, new Uint8Array(64), Bytes.fromString(PROVISIONING_INFO) ); const keys = Bytes.concatenate([aesKey, macKey]); const { ciphertext } = encryptAttachment( Proto.ArtProvisioningMessage.encode({ ...auth, }).finish(), keys ); const envelope = Proto.ArtProvisioningEnvelope.encode({ publicKey: ourKeys.pubKey, ciphertext, }).finish(); const socket = await server.getArtProvisioningSocket(token); try { await promisify(socket.sendBytes).call(socket, Buffer.from(envelope)); } finally { socket.close(1000, 'goodbye'); } }