UNPKG

nativescript-libsignal-protocol

Version:

A Libsignal-Protocol wrapper for NativeScript.

958 lines 46.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var LibsignalProtocol; (function (LibsignalProtocol) { var MemorySignalProtocolStore = (function () { function MemorySignalProtocolStore(identityKeyPair, registrationId) { this.Direction = { SENDING: 1, RECEIVING: 2, }; this.MemoryStore = new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId); } MemorySignalProtocolStore.prototype.getIdentityKeyPair = function () { return this.MemoryStore.getIdentityKeyPair(); }; MemorySignalProtocolStore.prototype.getLocalRegistrationId = function () { return this.MemoryStore.getLocalRegistrationId(); }; MemorySignalProtocolStore.prototype.saveIdentity = function (address, identityKey) { return this.MemoryStore.saveIdentity(address, identityKey); }; MemorySignalProtocolStore.prototype.isTrustedIdentity = function (address, identityKey, direction) { return this.MemoryStore(address, identityKey, direction); }; MemorySignalProtocolStore.prototype.getIdentity = function (address) { return this.MemoryStore.getIdentity(address); }; MemorySignalProtocolStore.prototype.loadPreKey = function (preKeyId) { return this.MemoryStore.loadPreKey(preKeyId); }; MemorySignalProtocolStore.prototype.storePreKey = function (preKeyId, record) { return this.MemoryStore.storePreKey(preKeyId, record); }; MemorySignalProtocolStore.prototype.containsPreKey = function (preKeyId) { return this.MemoryStore.containsPreKey(preKeyId); }; MemorySignalProtocolStore.prototype.removePreKey = function (preKeyId) { return this.MemoryStore.removePreKey(preKeyId); }; MemorySignalProtocolStore.prototype.loadSession = function (address) { return this.MemoryStore.loadSession(address); }; MemorySignalProtocolStore.prototype.getSubDeviceSessions = function (name) { return this.MemoryStore.getSubDeviceSessions(name); }; MemorySignalProtocolStore.prototype.storeSession = function (address, record) { return this.MemoryStore.storeSession(address, record); }; MemorySignalProtocolStore.prototype.containsSession = function (address) { return this.MemoryStore.containsSession(address); }; MemorySignalProtocolStore.prototype.deleteSession = function (address) { return this.MemoryStore.deleteSession(address); }; MemorySignalProtocolStore.prototype.deleteAllSessions = function (name) { return this.MemoryStore.deleteAllSessions(name); }; MemorySignalProtocolStore.prototype.loadSignedPreKey = function (signedPreKeyId) { return this.MemoryStore.loadSignedPreKey(signedPreKeyId); }; MemorySignalProtocolStore.prototype.loadSignedPreKeys = function () { return this.MemoryStore.loadSignedPreKeys(); }; MemorySignalProtocolStore.prototype.storeSignedPreKey = function (signedPreKeyId, record) { return this.MemoryStore.storeSignedPreKey(signedPreKeyId, record); }; MemorySignalProtocolStore.prototype.containsSignedPreKey = function (signedPreKeyId) { return this.MemoryStore.containsSignedPreKey(signedPreKeyId); }; MemorySignalProtocolStore.prototype.removeSignedPreKey = function (signedPreKeyId) { return this.MemoryStore.removeSignedPreKey(signedPreKeyId); }; return MemorySignalProtocolStore; }()); LibsignalProtocol.MemorySignalProtocolStore = MemorySignalProtocolStore; var SessionCipher = (function () { function SessionCipher(store, remoteAddress) { this.CipherStore = new org.whispersystems.libsignal.SessionCipher(store, remoteAddress); } SessionCipher.prototype.encrypt = function (paddedMessage) { return this.CipherStore.encrypt(paddedMessage); }; SessionCipher.prototype.decrypt = function (ciphertext, callback) { if (typeof callback === 'undefined') return this.CipherStore.decrypt(ciphertext, callback); return this.CipherStore.decrypt(ciphertext); }; return SessionCipher; }()); LibsignalProtocol.SessionCipher = SessionCipher; var InMemorySignalProtocolStore = (function () { function InMemorySignalProtocolStore() { this.store = {}; this.Direction = { SENDING: 1, RECEIVING: 2, }; } InMemorySignalProtocolStore.prototype.getIdentityKeyPair = function () { return Promise.resolve(this.get('identityKey')); }; InMemorySignalProtocolStore.prototype.getLocalRegistrationId = function () { return Promise.resolve(this.get('registrationId')); }; InMemorySignalProtocolStore.prototype.put = function (key, value) { if (key === undefined || value === undefined || key === null || value === null) throw new Error('Tried to store undefined/null'); this.store[key] = value; }; InMemorySignalProtocolStore.prototype.get = function (key, defaultValue) { if (key === null || key === undefined) throw new Error('Tried to get value for undefined/null key'); if (key in this.store) { return this.store[key]; } else { return defaultValue; } }; InMemorySignalProtocolStore.prototype.remove = function (key) { if (key === null || key === undefined) throw new Error('Tried to remove value for undefined/null key'); delete this.store[key]; }; InMemorySignalProtocolStore.prototype.isTrustedIdentity = function (identifier, identityKey, direction) { if (identifier === null || identifier === undefined) { throw new Error('tried to check identity key for undefined/null key'); } if (!(identityKey instanceof ArrayBuffer)) { throw new Error('Expected identityKey to be an ArrayBuffer'); } var trusted = this.get('identityKey' + identifier); if (trusted === undefined) { return Promise.resolve(true); } return Promise.resolve(LibsignalProtocol.Util.isEqualString(identityKey, trusted)); }; InMemorySignalProtocolStore.prototype.loadIdentityKey = function (identifier) { if (identifier === null || identifier === undefined) throw new Error('Tried to get identity key for undefined/null key'); return Promise.resolve(this.get('identityKey' + identifier)); }; InMemorySignalProtocolStore.prototype.saveIdentity = function (identifier, identityKey) { if (identifier === null || identifier === undefined) throw new Error('Tried to put identity key for undefined/null key'); if (typeof identifier !== 'string' || !identifier.match(/.*\.\d+/)) { throw new Error('Invalid SignalProtocolAddress string'); } var parts = identifier.split('.'); var address = new org.whispersystems.libsignal.SignalProtocolAddress(parts[0], parseInt(parts[1])); var existing = this.get('identityKey' + address.getName()); this.put('identityKey' + address.getName(), identityKey); if (existing && !LibsignalProtocol.Util.isEqualString(identityKey, existing)) { return Promise.resolve(true); } else { return Promise.resolve(false); } }; InMemorySignalProtocolStore.prototype.loadPreKey = function (keyId) { var res = this.get('25519KeypreKey' + keyId); if (res !== undefined) { res = { pubKey: res.pubKey, privKey: res.privKey }; } return Promise.resolve(res); }; InMemorySignalProtocolStore.prototype.storePreKey = function (keyId, keyPair) { return Promise.resolve(this.put('25519KeypreKey' + keyId, keyPair)); }; InMemorySignalProtocolStore.prototype.removePreKey = function (keyId) { return Promise.resolve(this.remove('25519KeypreKey' + keyId)); }; InMemorySignalProtocolStore.prototype.loadSignedPreKey = function (keyId) { var res = this.get('25519KeysignedKey' + keyId); if (res !== undefined) { res = { pubKey: res.pubKey, privKey: res.privKey }; } return Promise.resolve(res); }; InMemorySignalProtocolStore.prototype.storeSignedPreKey = function (keyId, keyPair) { return Promise.resolve(this.put('25519KeysignedKey' + keyId, keyPair)); }; InMemorySignalProtocolStore.prototype.removeSignedPreKey = function (keyId) { return Promise.resolve(this.remove('25519KeysignedKey' + keyId)); }; InMemorySignalProtocolStore.prototype.loadSession = function (identifier) { return Promise.resolve(this.get('session' + identifier)); }; InMemorySignalProtocolStore.prototype.storeSession = function (identifier, record) { return Promise.resolve(this.put('session' + identifier, record)); }; InMemorySignalProtocolStore.prototype.removeSession = function (identifier) { return Promise.resolve(this.remove('session' + identifier)); }; InMemorySignalProtocolStore.prototype.removeAllSessions = function (identifier) { for (var id in this.store) { if (id.startsWith('session' + identifier)) { delete this.store[id]; } } return Promise.resolve(); }; return InMemorySignalProtocolStore; }()); LibsignalProtocol.InMemorySignalProtocolStore = InMemorySignalProtocolStore; var Util = (function () { function Util() { } Util.base64Encode = function (mixed) { return android.util.Base64.encodeToString(mixed, android.util.Base64.NO_WRAP); }; Util.base64Decode = function (base64Str) { return android.util.Base64.decode(base64Str, android.util.Base64.NO_WRAP); }; Util.base64ToArrayBuffer = function (base64) { var binary_string = Util.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes.buffer; }; Util.arrayBufferToBase64 = function (buffer) { var binary = ''; var bytes = new Uint8Array(buffer); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return Util.btoa(binary); }; Util.atob = function (str) { var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; str = String(str).replace(/[\t\n\f\r ]+/g, ""); if (!b64re.test(str)) throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded."); str += "==".slice(2 - (str.length & 3)); var bitmap, result = "", r1, r2, i = 0; for (; i < str.length;) { bitmap = b64.indexOf(str.charAt(i++)) << 18 | b64.indexOf(str.charAt(i++)) << 12 | (r1 = b64.indexOf(str.charAt(i++))) << 6 | (r2 = b64.indexOf(str.charAt(i++))); result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) : r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) : String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255); } return result; }; ; Util.btoa = function (str) { var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/; str = String(str); var bitmap, a, b, c, result = "", i = 0, rest = str.length % 3; for (; i < str.length;) { if ((a = str.charCodeAt(i++)) > 255 || (b = str.charCodeAt(i++)) > 255 || (c = str.charCodeAt(i++)) > 255) throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range."); bitmap = (a << 16) | (b << 8) | c; result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63); } return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result; }; ; Util.toString = function (value) { try { if (value === null) return ''; else if (typeof value === 'string') return value; else if (typeof value === 'number') return Number(value).toString(); else if (typeof value === 'function') return value.toString(); else if (typeof value === 'object') { if (value.hasOwnProperty('length')) return value.toString(); else return JSON.stringify(value); } else return java.lang.String.valueOf(value); } catch (err) { console.log("Unable to convert value.toString"); return ''; } }; Util.isEqualString = function (value, compared) { return !!(LibsignalProtocol.Util.toString(value) === LibsignalProtocol.Util.toString(compared)); }; return Util; }()); LibsignalProtocol.Util = Util; var Core = (function () { function Core() { } Core.importPreKeyRecord = function (serialized) { try { return new org.whispersystems.libsignal.state.PreKeyRecord(serialized); } catch (err) { console.log('ERROR -- Unable to import PreKeyRecord'); console.log(err.message ? err.message : '...'); } return null; }; Core.importSignedPreKeyRecord = function (serialized) { try { return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized); } catch (err) { console.log('ERROR -- Unable to import SignedPreKeyRecord'); console.log(err.message ? err.message : '...'); } return null; }; Core.importSignedPreKey = function (serialized) { return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized); }; Core.importIdentityKey = function (serialized) { try { return new org.whispersystems.libsignal.IdentityKey(serialized, 0); } catch (err) { console.log('ERROR -- Unable to import IdentityKey'); console.log(err.message ? err.message : '...'); } return null; }; Core.importIdentityKeyPair = function (serialized) { try { return new org.whispersystems.libsignal.IdentityKeyPair(serialized); } catch (err) { console.log('ERROR -- Unable to import IdentityKeyPair'); console.log(err.message ? err.message : '...'); } return null; }; Core.importPublicKey = function (serialized) { try { return org.whispersystems.libsignal.ecc.Curve.decodePoint(serialized, 0); } catch (err) { console.log('ERROR -- Unable to import ECPublicKey'); console.log(err.message ? err.message : '...'); } return null; }; Core.createPreKeySignalMessage = function (serialized) { try { return new org.whispersystems.libsignal.protocol.PreKeySignalMessage(serialized); } catch (err) { console.log('ERROR -- Unable to create PreKeySignalMessage'); } return null; }; Core.createSignalMessage = function (serialized) { try { return new org.whispersystems.libsignal.protocol.SignalMessage(serialized); } catch (err) { console.log('ERROR -- Unable to create SignalMessage'); console.log(err.message ? err.message : '...'); } return null; }; Core.createPreKeyRecord = function (id, keyPair) { return new org.whispersystems.libsignal.state.PreKeyRecord(id, keyPair); }; Core.createSignedPreKeyRecord = function (id, timestamp, keyPair, signature) { return new org.whispersystems.libsignal.state.SignedPreKeyRecord(id, timestamp, keyPair, signature); }; Core.createSignalProtocolStore = function (identityKeyPair, registrationId) { return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId); }; Core.createTestSignalProtocolStore = function () { function generateRegistrationId() { return org.whispersystems.libsignal.util.KeyHelper.generateRegistrationId(false); } function generateIdentityKeyPair() { var keyPair = Curve.generateKeyPair(); var publicKey = new org.whispersystems.libsignal.IdentityKey(keyPair.getPublicKey()); return new org.whispersystems.libsignal.IdentityKeyPair(publicKey, keyPair.getPrivateKey()); } return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(generateIdentityKeyPair(), generateRegistrationId()); }; Core.createIdentityKeyPair = function (publicKey, privateKey) { return new org.whispersystems.libsignal.IdentityKeyPair(publicKey, privateKey); }; Core.createIdentityKey = function (publicKey) { return new org.whispersystems.libsignal.IdentityKey(publicKey); }; Core.createSessionBuilder = function (store, address) { try { return new org.whispersystems.libsignal.SessionBuilder(store, address); } catch (err) { console.log('ERROR -- Unable to create SessionBuilder'); console.log(err.message ? err.message : '...'); } return null; }; Core.createSessionCipher = function (store, address) { return new org.whispersystems.libsignal.SessionCipher(store, address); }; Core.createMemorySignalProtocolStore = function (identityKeyPair, registrationId) { return new org.whispersystems.libsignal.state.impl.InMemorySignalProtocolStore(identityKeyPair, registrationId); }; Core.createSessionRecord = function () { return new org.whispersystems.libsignal.state.SessionRecord(); }; Core.createSignalProtocolAddress = function (registrationId, deviceId) { try { return new org.whispersystems.libsignal.SignalProtocolAddress(registrationId + '', deviceId); } catch (err) { console.log('ERROR -- Unable to create SignalProtocolAddress'); console.log(err.message ? err.message : '...'); } return null; }; Core.createPreKeyBundle = function (registrationId, deviceId, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey) { try { return new org.whispersystems.libsignal.state.PreKeyBundle(registrationId, deviceId, preKeyId, preKeyPublic, signedPreKeyId, signedPreKeyPublic, signedPreKeySignature, identityKey); } catch (err) { console.log('ERROR -- Unable to create PreKeyBundle'); console.log(err.message ? err.message : '...'); } return null; }; return Core; }()); LibsignalProtocol.Core = Core; var Curve = (function () { function Curve() { } Curve.generateKeyPair = function () { try { return new org.whispersystems.libsignal.ecc.Curve.generateKeyPair(); } catch (err) { console.log('ERROR -- Unable to generate KeyPair'); console.log(err.message ? err.message : '...'); } return null; }; Curve.calculateSignature = function (signingKey, message) { try { return new org.whispersystems.libsignal.ecc.Curve.calculateSignature(signingKey, message); } catch (err) { console.log('ERROR -- Unable to calculate signature'); console.log(err.message ? err.message : '...'); } return null; }; return Curve; }()); LibsignalProtocol.Curve = Curve; var KeyHelper = (function () { function KeyHelper() { } KeyHelper.generateRegistrationId = function (extendedRange) { if (typeof extendedRange === 'undefined') extendedRange = false; return org.whispersystems.libsignal.util.KeyHelper.generateRegistrationId(extendedRange); }; KeyHelper.generateIdentityKeyPair = function () { try { return org.whispersystems.libsignal.util.KeyHelper.generateIdentityKeyPair(); } catch (err) { console.log('ERROR -- Unable to generate IdentityKeyPair'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.generateIdentityKeyPairFormatted = function () { try { var IDKeyPair = org.whispersystems.libsignal.util.KeyHelper.generateIdentityKeyPair(); return { pubKey: Util.base64Encode(IDKeyPair.getPublicKey().serialize()), privKey: Util.base64Encode(IDKeyPair.getPrivateKey().serialize()), }; } catch (err) { console.log('ERROR -- Unable to generate IdentityKeyPairFormatted'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.generateKeyPair = function (pubKey, privKey) { return new org.whispersystems.libsignal.ecc.ECKeyPair(pubKey, privKey); }; KeyHelper.importIdentityKeyPair = function (serialized) { return new org.whispersystems.libsignal.IdentityKeyPair(serialized); }; KeyHelper.importSignedPreKeyRecord = function (serialized) { return new org.whispersystems.libsignal.state.SignedPreKeyRecord(serialized); }; KeyHelper.importSignalProtocolAddress = function (name, deviceId) { return new org.whispersystems.libsignal.SignalProtocolAddress(name, deviceId); }; KeyHelper.generatePreKeys = function (start, count) { try { return org.whispersystems.libsignal.util.KeyHelper.generatePreKeys(start, count); } catch (err) { console.log('ERROR -- Unable to generate PreKeyBundle'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.generatePreKeysFormatted = function (start, count) { try { var result = []; var preKeys = org.whispersystems.libsignal.util.KeyHelper.generatePreKeys(start, count); for (var i = 0; i < preKeys.size(); i++) { var key = preKeys.get(i); var keyPair = key.getKeyPair(); result.push({ keyId: key.getId(), keyPair: { pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()), privKey: Util.base64Encode(keyPair.getPrivateKey().serialize()) }, serialized: Util.base64Encode(key.serialize()) }); } return result; } catch (err) { console.log('ERROR -- Unable to generate PreKeyBundleFormatted'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.generateLastResortPreKeyRecord = function () { var keyPair = Curve.generateKeyPair(); return new org.whispersystems.libsignal.state.PreKeyRecord(0xFFFFFF, keyPair); }; KeyHelper.generateSignedPreKey = function (identityKeyPair, signedPreKeyId) { try { return org.whispersystems.libsignal.util.KeyHelper.generateSignedPreKey(identityKeyPair, signedPreKeyId); } catch (err) { console.log('ERROR -- Unable to generate SignedPreKey'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.generateSignedPreKeyFormatted = function (identityKeyPair, signedPreKeyId) { try { var signedPreKey = org.whispersystems.libsignal.util.KeyHelper.generateSignedPreKey(identityKeyPair, signedPreKeyId); return { keyId: signedPreKey.getId(), keyPair: { pubKey: Util.base64Encode(signedPreKey.getKeyPair().getPublicKey().serialize()), privKey: Util.base64Encode(signedPreKey.getKeyPair().getPrivateKey().serialize()), }, signature: Util.base64Encode(signedPreKey.getSignature()) }; } catch (err) { console.log('ERROR -- Unable to generate SignedPreKey'); console.log(err.message ? err.message : '...'); } return null; }; KeyHelper.verifySignedPreKey = function (signingKey, message, signature) { return org.whispersystems.libsignal.ecc.Curve.verifySignature(signingKey, message, signature); }; return KeyHelper; }()); LibsignalProtocol.KeyHelper = KeyHelper; var ClientInfo = (function () { function ClientInfo(identityKey, registrationId, deviceId, preKeys, signedPreKeyId, signedPreKey, signedPreKeySignature) { this.identityKey = identityKey; this.registrationId = registrationId; this.deviceId = deviceId; this.preKeys = preKeys; this.signedPreKeyId = signedPreKeyId; this.signedPreKey = signedPreKey; this.signedPreKeySignature = signedPreKeySignature; } ClientInfo.prototype.fetchPreKey = function (preKeyIndex) { var preKey = this.preKeys.splice(preKeyIndex, 1); return preKey[0]; }; ClientInfo.prototype.getPreKeyBundle = function () { var random = new java.util.Random(); var preKeyIds = Object.keys(this.preKeys); var preKeyIndex = preKeyIds[random.nextInt(preKeyIds.length)]; var preKey = this.fetchPreKey(preKeyIndex); return { registrationId: this.registrationId, deviceId: this.deviceId, preKeyPublic: preKey.pubKey, preKeyRecordId: preKey.id, signedPreKeyPublic: this.signedPreKey, signedPreKeyRecordId: this.signedPreKeyId, signature: this.signedPreKeySignature, identityPubKey: this.identityKey }; }; return ClientInfo; }()); LibsignalProtocol.ClientInfo = ClientInfo; var Client = (function () { function Client(clientName, registrationId, deviceId, identityKeyPairStr, signedPreKeyStr, importedPreKeys, contacts) { this.username = clientName; this.deviceId = deviceId; this.registrationId = registrationId; this.random = new java.util.Random(); this.contacts = []; this.preKeys = []; this.identityKeyPair; this.signedPreKey; this.createAddress(); this.createIdentityKeyPair(identityKeyPairStr); this.createSignedPreKey(signedPreKeyStr); this.store = Core.createMemorySignalProtocolStore(this.identityKeyPair, this.registrationId); this.store.storeSignedPreKey(this.signedPreKey.getId(), this.signedPreKey); var lastResortPreKeyRecord = KeyHelper.generateLastResortPreKeyRecord(); this.store.storePreKey(lastResortPreKeyRecord.getId(), lastResortPreKeyRecord); this.createPreKeys(importedPreKeys); this.createContacts(contacts); } Client.prototype.hasContact = function (contactName) { var contactIndex = this.contacts.findIndex(function (contact) { return !!(contact.name === contactName); }); return !!(contactIndex >= 0); }; Client.prototype.getContact = function (contactName) { return this.contacts.find(function (contact) { return !!(contact.name === contactName); }); }; Client.prototype.getContactIndex = function (contactName) { return this.contacts.findIndex(function (contact) { return !!(contact.name === contactName); }); }; Client.prototype.getSessionRecord = function (contactName) { if (!this.hasContact(contactName)) return false; var contact = this.getContact(contactName); return this.store.loadSession(contact.signalAddress); }; Client.prototype.hasSession = function (contactName) { if (!this.hasContact(contactName)) return false; var contact = this.getContact(contactName); return !!(this.store.containsSession(contact.signalAddress)); }; Client.prototype.hasPreKey = function (preKeyId) { return !!(this.store.containsPreKey(preKeyId)); }; Client.prototype.hasSignedPreKey = function (signedPreKeyId) { return !!(this.store.containsSignedPreKey(signedPreKeyId)); }; Client.prototype.generatePreKeyBatch = function (startFrom) { var _this = this; if (typeof startFrom === 'undefined') startFrom = this.random.nextInt(0xFFFFFF - 101); var preKeys = KeyHelper.generatePreKeysFormatted(startFrom, 100); preKeys.forEach(function (preKey) { try { _this.preKeys.push({ id: preKey.keyId, pubKey: preKey.keyPair.pubKey, serialized: preKey.serialized }); var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKey.serialized)); _this.store.storePreKey(preKeyRecord.getId(), preKeyRecord); } catch (err) { console.log('Unable to import prekey batch'); console.log(err); } }); return preKeys.map(function (preKey) { return { id: preKey.keyId, pubKey: preKey.keyPair.pubKey, serialized: preKey.serialized }; }); }; Client.prototype.importPreKeys = function (preKeys) { return __awaiter(this, void 0, void 0, function () { var _this = this; return __generator(this, function (_a) { if (typeof preKeys === 'undefined') { console.log('No prekeys provided to import!'); return [2, false]; } preKeys.forEach(function (_key) { var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(_key.serialized)); var keyPair = preKeyRecord.getKeyPair(); _this.preKeys.push({ id: preKeyRecord.getId(), pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()), serialized: Util.base64Encode(preKeyRecord.serialize()) }); _this.store.storePreKey(preKeyRecord.getId(), preKeyRecord); }); return [2, true]; }); }); }; Client.prototype.exportRegistrationObj = function () { return { address: { name: this.address.getName(), deviceId: this.address.getDeviceId(), registrationId: this.store.getLocalRegistrationId() }, identityPubKey: Util.base64Encode(this.store.getIdentityKeyPair().getPublicKey().serialize()), signedPreKey: { id: this.signedPreKey.getId(), pubKey: Util.base64Encode(this.signedPreKey.getKeyPair().getPublicKey().serialize()), signature: Util.base64Encode(this.signedPreKey.getSignature()) }, preKeys: this.preKeys.map(function (key) { return { id: key.id, pubKey: key.pubKey }; }) }; }; Client.prototype.addSession = function (contact, contactBundle) { try { var signalAddress = Core.createSignalProtocolAddress(contact.registrationId, contact.deviceId); var preKeyBundle = this.importPreKeyBundle(signalAddress, contactBundle); var sessionBuilder = Core.createSessionBuilder(this.store, signalAddress); sessionBuilder.process(preKeyBundle); var sessionCipher = Core.createSessionCipher(this.store, signalAddress); if (this.hasContact(contact.name)) { console.log('updating contact'); var nContact = this.getContactIndex(contact.name); this.contacts[nContact].sessionCipher = sessionCipher; } else { console.log('creating contact'); this.contacts.push({ name: contact.name, registrationId: contact.registrationId, deviceId: contact.deviceId, preKeyBundle: contactBundle, sessionCipher: sessionCipher, signalAddress: signalAddress }); } return Promise.resolve(true); } catch (err) { console.log("Unable to add session for [" + contact.name + "]"); console.log(err.message ? err.message : err); throw new Error('bad_session'); } }; Client.prototype.prepareMessage = function (contactName, message) { if (!this.hasContact(contactName)) { throw new Error('missing_contact'); } var cipher = this.getContact(contactName).sessionCipher; return Promise.resolve(this.encryptMessage(message, cipher)); }; Client.prototype.encodeMessage = function (message) { return Promise.resolve(Util.base64Encode(message)); }; Client.prototype.decodeMessage = function (message) { return Promise.resolve(Util.base64Decode(message)); }; Client.prototype.decryptEncodedMessage = function (contactName, message) { return __awaiter(this, void 0, void 0, function () { var decodedMessage, cipher; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!this.hasContact(contactName)) { throw new Error('missing_contact'); } return [4, this.decodeMessage(message)]; case 1: decodedMessage = _a.sent(); cipher = this.getContact(contactName).sessionCipher; return [2, Promise.resolve(this.decryptMessage(decodedMessage, cipher))]; } }); }); }; Client.prototype.toJSON = function () { return { username: this.username, deviceId: this.deviceId, registrationId: this.registrationId, address: { name: this.registrationId, deviceId: this.deviceId }, identityKeyPair: Util.base64Encode(this.store.getIdentityKeyPair().serialize()), signedPreKey: Util.base64Encode(this.signedPreKey.serialize()), contacts: this.contacts.map(function (c) { return { "address": { "name": c.name, "registrationId": c.registrationId, "deviceId": c.deviceId, }, "preKeyBundle": { "registrationId": c.preKeyBundle.registrationId, "deviceId": c.preKeyBundle.deviceId, "preKeyPublic": c.preKeyBundle.preKeyPublic, "preKeyRecordId": c.preKeyBundle.preKeyRecordId, "signedPreKeyPublic": c.preKeyBundle.signedPreKeyPublic, "signedPreKeyRecordId": c.preKeyBundle.signedPreKeyRecordId, "signature": c.preKeyBundle.signature, "identityPubKey": c.preKeyBundle.identityPubKey } }; }), preKeys: this.preKeys }; }; Client.prototype.serialize = function () { var serialize = { client: { registrationId: this.registrationId, username: this.username, deviceId: this.deviceId }, contacts: this.contacts, signedPreKey: Util.base64Encode(this.signedPreKey.serialize()), identityKeyPair: Util.base64Encode(this.store.getIdentityKeyPair().serialize()), preKeys: this.preKeys }; return JSON.stringify(serialize); }; Client.prototype.importPreKeyBundle = function (signalAddress, importedData) { var identityPubKey = Core.importIdentityKey(Util.base64Decode(importedData.identityPubKey)); return Core.createPreKeyBundle(Number(signalAddress.getName()), Number(signalAddress.getDeviceId()), importedData.preKeyRecordId, Core.importPublicKey(Util.base64Decode(importedData.preKeyPublic)), importedData.signedPreKeyRecordId, Core.importPublicKey(Util.base64Decode(importedData.signedPreKeyPublic)), Util.base64Decode(importedData.signature), identityPubKey); }; Client.prototype.encryptMessage = function (message, sessionCipher) { var javaStr = new java.lang.String(message); return sessionCipher.encrypt(javaStr.getBytes("UTF-8")).serialize(); }; Client.prototype.decryptMessage = function (message, cipher) { var signalMessage; try { signalMessage = Core.createPreKeySignalMessage(message); if (signalMessage) { console.log('isPreKeySignalMessage'); var text = cipher.decrypt(signalMessage); return new java.lang.String(text).toString(); } else { console.log('Failed PreKeySignalMessage will try SignalMessage'); signalMessage = Core.createSignalMessage(message); var text = cipher.decrypt(signalMessage); return new java.lang.String(text).toString(); } } catch (err) { console.log('Unable to decrypt[1]'); console.log(err); } return new Error('Unable to decrypt[2]'); }; Client.prototype.createAddress = function () { this.address = Core.createSignalProtocolAddress(this.username, this.deviceId); return this.address; }; Client.prototype.createIdentityKeyPair = function (importedIdentityKeyPair) { if (typeof importedIdentityKeyPair === 'undefined') { this.identityKeyPair = KeyHelper.generateIdentityKeyPair(); } else { this.identityKeyPair = Core.importIdentityKeyPair(Util.base64Decode(importedIdentityKeyPair)); } return this.identityKeyPair; }; Client.prototype.createSignedPreKey = function (importedSignedPreKey) { if (typeof importedSignedPreKey === 'undefined') { this.signedPreKey = KeyHelper.generateSignedPreKey(this.identityKeyPair, this.random.nextInt(0xFFFFFF - 1)); } else { this.signedPreKey = Core.importSignedPreKeyRecord(Util.base64Decode(importedSignedPreKey)); } return this.signedPreKey; }; Client.prototype.createPreKeys = function (importedPreKeys) { var _this = this; if (typeof importedPreKeys === 'undefined') { var preKeys = KeyHelper.generatePreKeysFormatted(this.random.nextInt(0xFFFFFF - 101), 100); preKeys.forEach(function (preKeyFormatted) { try { _this.preKeys.push({ id: preKeyFormatted.keyId, pubKey: preKeyFormatted.keyPair.pubKey, serialized: preKeyFormatted.serialized }); var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKeyFormatted.serialized)); _this.store.storePreKey(preKeyRecord.getId(), preKeyRecord); } catch (err) { console.log('nope2'); console.log(err); } }); } else { importedPreKeys.forEach(function (preKey) { var preKeyRecord = Core.importPreKeyRecord(Util.base64Decode(preKey.serialized)); var keyPair = preKeyRecord.getKeyPair(); _this.preKeys.push({ id: preKeyRecord.getId(), pubKey: Util.base64Encode(keyPair.getPublicKey().serialize()), serialized: Util.base64Encode(preKeyRecord.serialize()) }); _this.store.storePreKey(preKeyRecord.getId(), preKeyRecord); }); } return this.preKeys; }; Client.prototype.createContacts = function (importedContacts) { var _this = this; if (typeof importedContacts !== 'undefined' && importedContacts.length > 0) { importedContacts.forEach(function (contact) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4, this.addSession(contact.address, contact.preKeyBundle)]; case 1: _a.sent(); console.log("...added " + contact.address.name + " for " + this.username, { hasContact: this.hasContact(contact.address.name), hasSession: this.hasSession(contact.address.name) }); return [2]; } }); }); }); } return this.contacts; }; return Client; }()); LibsignalProtocol.Client = Client; })(LibsignalProtocol = exports.LibsignalProtocol || (exports.LibsignalProtocol = {})); //# sourceMappingURL=libsignal-protocol.android.js.map