Added libsignal-protocol typings.

Added MessageEncrypter.
pull/1153/head
Mikunj 5 years ago
parent 4dd8c433c9
commit 36762dbbf2

@ -149,10 +149,13 @@
myPrivateKey
);
const ivAndCiphertext = await DHEncrypt(symmetricKey, plaintext);
const binaryIvAndCiphertext = dcodeIO.ByteBuffer.wrap(
ivAndCiphertext
).toString('binary');
return {
type: textsecure.protobuf.Envelope.Type.FRIEND_REQUEST,
body: ivAndCiphertext,
registrationId: null,
body: binaryIvAndCiphertext,
registrationId: undefined,
};
}

@ -0,0 +1,120 @@
import { SignalService } from '../ts/protobuf';
export type BinaryString = String;
export type CipherTextObject = {
type: SignalService.Envelope.Type;
body: BinaryString;
registrationId?: number;
};
export declare class SignalProtocolAddress {
constructor(hexEncodedPublicKey: string, deviceId: number);
getName(): string;
getDeviceId(): number;
toString(): string;
equals(other: SignalProtocolAddress): boolean;
static fromString(encodedAddress: string): SignalProtocolAddress;
}
export type KeyPair = {
pubKey: ArrayBuffer;
privKey: ArrayBuffer;
};
interface CurveSync {
generateKeyPair(): KeyPair;
createKeyPair(privKey: ArrayBuffer): KeyPair;
calculateAgreement(pubKey: ArrayBuffer, privKey: ArrayBuffer): ArrayBuffer;
verifySignature(pubKey: ArrayBuffer, msg: ArrayBuffer, sig: ArrayBuffer);
calculateSignature(privKey: ArrayBuffer, message: ArrayBuffer): ArrayBuffer;
validatePubKeyFormat(pubKey: ArrayBuffer): ArrayBuffer;
}
interface CurveAsync {
generateKeyPair(): Promise<KeyPair>;
createKeyPair(privKey: ArrayBuffer): Promise<KeyPair>;
calculateAgreement(
pubKey: ArrayBuffer,
privKey: ArrayBuffer
): Promise<ArrayBuffer>;
verifySignature(
pubKey: ArrayBuffer,
msg: ArrayBuffer,
sig: ArrayBuffer
): Promise<void>;
calculateSignature(
privKey: ArrayBuffer,
message: ArrayBuffer
): Promise<ArrayBuffer>;
validatePubKeyFormat(pubKey: ArrayBuffer): Promise<ArrayBuffer>;
}
export interface CurveInterface extends CurveSync {
async: CurveAsync;
}
export interface CryptoInterface {
encrypt(
key: ArrayBuffer,
data: ArrayBuffer,
iv: ArrayBuffer
): Promise<ArrayBuffer>;
decrypt(
key: ArrayBuffer,
data: ArrayBuffer,
iv: ArrayBuffer
): Promise<ArrayBuffer>;
calculateMAC(key: ArrayBuffer, data: ArrayBuffer): Promise<ArrayBuffer>;
verifyMAC(
data: ArrayBuffer,
key: ArrayBuffer,
mac: ArrayBuffer,
length: number
): Promise<void>;
getRandomBytes(size: number): ArrayBuffer;
}
export interface KeyHelperInterface {
generateIdentityKeyPair(): Promise<KeyPair>;
generateRegistrationId(): number;
generateSignedPreKey(
identityKeyPair: KeyPair,
signedKeyId: number
): Promise<{
keyId: number;
keyPair: KeyPair;
signature: ArrayBuffer;
}>;
generatePreKey(
keyId: number
): Promise<{
keyId: number;
keyPair: KeyPair;
}>;
}
export declare class SessionCipher {
constructor(storage: any, remoteAddress: SignalProtocolAddress);
/**
* @returns The envelope type, registration id and binary encoded encrypted body.
*/
encrypt(buffer: ArrayBuffer | Uint8Array): Promise<CipherTextObject>;
decryptPreKeyWhisperMessage(
buffer: ArrayBuffer | Uint8Array
): Promise<ArrayBuffer>;
decryptWhisperMessage(buffer: ArrayBuffer | Uint8Array): Promise<ArrayBuffer>;
getRecord(encodedNumber: string): Promise<any | undefined>;
getRemoteRegistrationId(): Promise<number>;
hasOpenSession(): Promise<boolean>;
closeOpenSessionForDevice(): Promise<void>;
deleteAllSessionsForDevice(): Promise<void>;
}
export interface LibsignalProtocol {
SignalProtocolAddress: typeof SignalProtocolAddress;
Curve: CurveInterface;
crypto: CryptoInterface;
KeyHelper: KeyHelperInterface;
SessionCipher: typeof SessionCipher;
}

@ -1,5 +1,10 @@
import { EncryptionType } from '../types/EncryptionType';
import { SignalService } from '../../protobuf';
import { libloki, libsignal, textsecure } from '../../window';
import {
CipherTextObject,
SignalProtocolAddress,
} from '../../../libtextsecure/libsignal-protocol';
function padPlainTextBuffer(messageBuffer: Uint8Array): Uint8Array {
const plaintext = new Uint8Array(
@ -22,19 +27,57 @@ function getPaddedMessageLength(originalLength: number): number {
return messagePartCount * 160;
}
export function encrypt(
export type Base64String = String;
/**
* Encrypt `plainTextBuffer` with given `encryptionType` for `device`.
*
* @param device The device to encrypt for.
* @param plainTextBuffer The unpadded plaintext buffer.
* @param encryptionType The type of encryption.
* @returns The envelope type and the base64 encoded cipher text
*/
export async function encrypt(
device: string,
plainTextBuffer: Uint8Array,
encryptionType: EncryptionType
): {
): Promise<{
envelopeType: SignalService.Envelope.Type;
cipherText: Uint8Array;
} {
cipherText: Base64String;
}> {
const plainText = padPlainTextBuffer(plainTextBuffer);
// TODO: Do encryption here?
const address = new libsignal.SignalProtocolAddress(device, 1);
if (encryptionType === EncryptionType.MediumGroup) {
// TODO: Do medium group stuff here
throw new Error('Encryption is not yet supported');
}
let cipherText: CipherTextObject;
if (encryptionType === EncryptionType.SessionReset) {
const cipher = new libloki.crypto.FallBackSessionCipher(address);
cipherText = await cipher.encrypt(plainText.buffer);
} else {
const cipher = new libsignal.SessionCipher(
textsecure.storage.protocol,
address
);
cipherText = await cipher.encrypt(plainText.buffer);
}
return encryptUsingSealedSender(address, cipherText);
}
async function encryptUsingSealedSender(
address: SignalProtocolAddress,
cipherText: CipherTextObject
): Promise<{
envelopeType: SignalService.Envelope.Type;
cipherText: Base64String;
}> {
// TODO: Do stuff here
return {
envelopeType: SignalService.Envelope.Type.CIPHERTEXT,
cipherText: new Uint8Array(),
envelopeType: SignalService.Envelope.Type.UNIDENTIFIED_SENDER,
cipherText: 'implement me!',
};
}

@ -1,6 +1,7 @@
import { LocalizerType } from './types/Util';
import { LibsignalProtocol } from '../libtextsecure/libsignal-protocol';
interface Window {
interface WindowInterface extends Window {
seedNodeList: any;
WebAPI: any;
@ -32,7 +33,7 @@ interface Window {
shortenPubkey: any;
dcodeIO: any;
libsignal: any;
libsignal: LibsignalProtocol;
libloki: any;
displayNameRegex: any;
@ -72,7 +73,9 @@ interface Window {
resetDatabase: any;
}
declare const window: Window;
declare const window: WindowInterface;
// TODO: Is there an easier way to dynamically export these?
// Utilities
export const WebAPI = window.WebAPI;
@ -118,3 +121,7 @@ export const clearLocalData = window.clearLocalData;
export const deleteAccount = window.deleteAccount;
export const resetDatabase = window.resetDatabase;
export const attemptConnection = window.attemptConnection;
export const libloki = window.libloki;
export const libsignal = window.libsignal;
export const textsecure = window.textsecure;

Loading…
Cancel
Save