UNPKG

proteus-hd

Version:

Signal Protocol (with header encryption) implementation for JavaScript. Based on Proteus.js.

2,048 lines (1,715 loc) 196 kB
/*! proteus-hd v1.0.4 */ var Proteus = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 33); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const ProteusError = __webpack_require__(6); /** @module errors */ const _extend = function(child, parent) { for (let key in parent) { if ({}.hasOwnProperty.call(parent, key)) child[key] = parent[key]; } const ctor = function() { this.constructor = child; }; ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; /** * @class DontCallConstructor * @extends Error * @returns {DontCallConstructor} - `this` */ const DontCallConstructor = (function(superClass) { _extend(func, superClass); function func(_instance) { this._instance = _instance; func.__super__.constructor.call(this, `Instead of 'new {this._instance.constructor.name}', use '${this._instance.constructor.name}.new'.` ); } return func; })(ProteusError); module.exports = DontCallConstructor; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const InputError = __webpack_require__(20); /** @module util */ const TypeUtil = { /** * @param {*} classes * @param {*} inst * @returns {void} * @throws {errors.InputError.TypeError} */ assert_is_instance(classes, inst) { if (!Array.isArray(classes)) { classes = [classes]; } if (classes.some((k) => inst instanceof k || (inst && inst.prototype instanceof k))) { return; } const valid_types = classes.map((k) => `'${k.name}'`).join(' or '); if (inst) { throw new InputError.TypeError(`Expected one of ${valid_types}, got '${inst.constructor.name}'.`, InputError.CODE.CASE_401); } throw new InputError.TypeError(`Expected one of ${valid_types}, got '${String(inst)}'.`, InputError.CODE.CASE_402); }, /** * @param {*} inst * @returns {boolean} * @throws {errors.InputError.TypeError} */ assert_is_integer(inst) { if (Number.isInteger(inst)) { return true; } if (inst) { throw new InputError.TypeError(`Expected integer, got '${inst.constructor.name}'.`, InputError.CODE.CASE_403); } throw new InputError.TypeError(`Expected integer, got '${String(inst)}'.`, InputError.CODE.CASE_404); }, }; module.exports = TypeUtil; /***/ }), /* 2 */ /***/ (function(module, exports) { module.exports = CBOR; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const DontCallConstructor = __webpack_require__(0); /** @module util */ const ClassUtil = { /** * @param {*} klass * @returns {Function} */ new_instance(klass) { try { return new klass(); } catch (e) { if (!(e instanceof DontCallConstructor)) { throw e; } return e._instance; } }, }; module.exports = ClassUtil; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ed2curve = __webpack_require__(21); const sodium = __webpack_require__(5); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); /** @module keys */ /** * @class PublicKey * @throws {DontCallConstructor} */ class PublicKey { constructor() { throw new DontCallConstructor(this); } /** * @param {!Uint8Array} pub_edward * @param {!Uint8Array} pub_curve * @returns {PublicKey} - `this` */ static new(pub_edward, pub_curve) { TypeUtil.assert_is_instance(Uint8Array, pub_edward); TypeUtil.assert_is_instance(Uint8Array, pub_curve); /** @type {PublicKey} */ const pk = ClassUtil.new_instance(PublicKey); /** @type {Uint8Array} */ pk.pub_edward = pub_edward; /** @type {Uint8Array} */ pk.pub_curve = pub_curve; return pk; } /** * This function can be used to verify a message signature. * * @param {!Uint8Array} signature - The signature to verify * @param {!string} message - The message from which the signature was computed. * @returns {boolean} - `true` if the signature is valid, `false` otherwise. */ verify(signature, message) { TypeUtil.assert_is_instance(Uint8Array, signature); return sodium.crypto_sign_verify_detached(signature, message, this.pub_edward); } /** @returns {string} */ fingerprint() { return sodium.to_hex(this.pub_edward); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(1); e.u8(0); return e.bytes(this.pub_edward); } /** * @param {!CBOR.Decoder} d * @returns {PublicKey} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); const self = ClassUtil.new_instance(PublicKey); const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: self.pub_edward = new Uint8Array(d.bytes()); break; default: d.skip(); } } TypeUtil.assert_is_instance(Uint8Array, self.pub_edward); self.pub_curve = ed2curve.convertPublicKey(self.pub_edward); return self; } } module.exports = PublicKey; /***/ }), /* 5 */ /***/ (function(module, exports) { module.exports = sodium; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /** @module errors */ /** * @class ProteusError * @param {!string} message * @param {string} [code] * @extends Error * @returns {ProteusError} - `this` */ const ProteusError = (function() { const func = function(message, code = 1) { this.code = code; this.message = message; this.name = this.constructor.name; this.stack = (new Error).stack; }; func.prototype = new Error; func.prototype.constructor = func; func.prototype.CODE = { CASE_100: 100, CASE_101: 101, CASE_102: 102, CASE_103: 103, CASE_104: 104, }; return func; })(); module.exports = ProteusError; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ed2curve = __webpack_require__(21); const sodium = __webpack_require__(5); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const PublicKey = __webpack_require__(4); const SecretKey = __webpack_require__(22); /** @module keys */ /** * Construct an ephemeral key pair. * @class KeyPair * @throws {DontCallConstructor} */ class KeyPair { constructor() { throw new DontCallConstructor(this); } /** @returns {KeyPair} - `this` */ static new() { const ed25519_key_pair = sodium.crypto_sign_keypair(); const kp = ClassUtil.new_instance(KeyPair); kp.secret_key = KeyPair.prototype._construct_private_key(ed25519_key_pair); kp.public_key = KeyPair.prototype._construct_public_key(ed25519_key_pair); return kp; } /** * @description Ed25519 keys can be converted to Curve25519 keys, so that the same key pair can be * used both for authenticated encryption (crypto_box) and for signatures (crypto_sign). * @param {!Uint8Array} ed25519_key_pair - Key pair based on Edwards-curve (Ed25519) * @returns {keys.SecretKey} - Constructed private key * @private * @see https://download.libsodium.org/doc/advanced/ed25519-curve25519.html */ _construct_private_key(ed25519_key_pair) { const sk_ed25519 = ed25519_key_pair.privateKey; const sk_curve25519 = ed2curve.convertSecretKey(sk_ed25519); return SecretKey.new(sk_ed25519, sk_curve25519); } /** * @typedef {Object} libsodium_keypair * @param {!Uint8Array} publicKey * @param {!Uint8Array} privateKey * @param {!string} keyType */ /** * @param {!libsodium_keypair} ed25519_key_pair - Key pair based on Edwards-curve (Ed25519) * @private * @returns {keys.PublicKey} - Constructed public key */ _construct_public_key(ed25519_key_pair) { const pk_ed25519 = ed25519_key_pair.publicKey; const pk_curve25519 = ed2curve.convertPublicKey(pk_ed25519); return PublicKey.new(pk_ed25519, pk_curve25519); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(2); e.u8(0); this.secret_key.encode(e); e.u8(1); return this.public_key.encode(e); } /** * @param {!CBOR.Decoder} d * @returns {KeyPair} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); const self = ClassUtil.new_instance(KeyPair); const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: self.secret_key = SecretKey.decode(d); break; case 1: self.public_key = PublicKey.decode(d); break; default: d.skip(); } } TypeUtil.assert_is_instance(SecretKey, self.secret_key); TypeUtil.assert_is_instance(PublicKey, self.public_key); return self; } } module.exports = KeyPair; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const sodium = __webpack_require__(5); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const PublicKey = __webpack_require__(4); /** @module keys */ /** * Construct a long-term identity key pair. * @classdesc Every client has a long-term identity key pair. * Long-term identity keys are used to initialise "sessions" with other clients (triple DH). * @throws {DontCallConstructor} */ class IdentityKey { constructor() { throw new DontCallConstructor(this); } /** * @param {!PublicKey} public_key * @returns {IdentityKey} - `this` */ static new(public_key) { TypeUtil.assert_is_instance(PublicKey, public_key); const key = ClassUtil.new_instance(IdentityKey); key.public_key = public_key; return key; } /** @returns {string} */ fingerprint() { return this.public_key.fingerprint(); } /** @returns {string} */ toString() { return sodium.to_hex(this.public_key); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(1); e.u8(0); return this.public_key.encode(e); } /** * @param {!CBOR.Decoder} d * @returns {IdentityKey} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); let public_key = null; const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: public_key = PublicKey.decode(d); break; default: d.skip(); } } return IdentityKey.new(public_key); } } module.exports = IdentityKey; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const Message = __webpack_require__(12); /** @module message */ /** * @extends Message * @throws {DontCallConstructor} */ class HeaderMessage extends Message { constructor() { super(); throw new DontCallConstructor(this); } /** * @param {!Uint8Array} encrypted_header - encrypted header * @param {!Uint8Array} cipher_text * @returns {HeaderMessage} - `this` */ static new(encrypted_header, cipher_text) { TypeUtil.assert_is_instance(Uint8Array, encrypted_header); TypeUtil.assert_is_instance(Uint8Array, cipher_text); const hm = ClassUtil.new_instance(HeaderMessage); hm.header = encrypted_header; hm.cipher_text = cipher_text; Object.freeze(hm); return hm; } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(2); e.u8(0); e.object(1); e.u8(0); e.bytes(this.header); e.u8(1); return e.bytes(this.cipher_text); } /** * @param {!CBOR.Decoder} d * @returns {HeaderMessage} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); let header = null; let cipher_text = null; const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: { const nprops_mac = d.object(); for (let j = 0; j <= nprops_mac - 1; j++) { switch (d.u8()) { case 0: header = new Uint8Array(d.bytes()); break; default: d.skip(); } } break; } case 1: { cipher_text = new Uint8Array(d.bytes()); break; } default: { d.skip(); } } } return HeaderMessage.new(header, cipher_text); } } module.exports = HeaderMessage; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const ProteusError = __webpack_require__(6); /** @module errors */ /** * @extends ProteusError * @param {string} [message] * @param {string} [code] */ class DecryptError extends ProteusError { constructor(message = 'Unknown decryption error', code = 2) { super(message, code); } static get CODE() { return { CASE_200: 200, CASE_201: 201, CASE_202: 202, CASE_203: 203, CASE_204: 204, CASE_205: 205, CASE_206: 206, CASE_207: 207, CASE_208: 208, CASE_209: 209, CASE_210: 210, CASE_211: 211, CASE_212: 212, CASE_213: 213, CASE_214: 214, CASE_215: 215, CASE_216: 216, }; } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class RemoteIdentityChanged extends DecryptError { constructor(message = 'Remote identity changed', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class InvalidSignature extends DecryptError { constructor(message = 'Invalid signature', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class InvalidMessage extends DecryptError { constructor(message = 'Invalid message', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class DuplicateMessage extends DecryptError { constructor(message = 'Duplicate message', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class TooDistantFuture extends DecryptError { constructor(message = 'Message is from too distant in the future', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class OutdatedMessage extends DecryptError { constructor(message = 'Outdated message', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class PrekeyNotFound extends DecryptError { constructor(message = 'Pre-key not found', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class HeaderDecryptionFailed extends DecryptError { constructor(message = 'Header descryption failed', code) { super(message, code); } } /** * @extends DecryptError * @param {string} [message] * @param {string} [code] */ class InvalidHeader extends DecryptError { constructor(message = 'Invalid header', code) { super(message, code); } } Object.assign(DecryptError, { RemoteIdentityChanged, InvalidSignature, InvalidMessage, DuplicateMessage, TooDistantFuture, OutdatedMessage, PrekeyNotFound, HeaderDecryptionFailed, InvalidHeader, }); module.exports = ProteusError.DecryptError = DecryptError; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const IdentityKey = __webpack_require__(8); const KeyPair = __webpack_require__(7); const SecretKey = __webpack_require__(22); /** @module keys */ /** * @class IdentityKeyPair * @throws {DontCallConstructor} */ class IdentityKeyPair { constructor() { throw new DontCallConstructor(this); } /** @returns {IdentityKeyPair} - `this` */ static new() { const key_pair = KeyPair.new(); /** @type {IdentityKeyPair} */ const ikp = ClassUtil.new_instance(IdentityKeyPair); ikp.version = 1; ikp.secret_key = key_pair.secret_key; ikp.public_key = IdentityKey.new(key_pair.public_key); return ikp; } /** @returns {ArrayBuffer} */ serialise() { const e = new CBOR.Encoder(); this.encode(e); return e.get_buffer(); } /** * @param {!ArrayBuffer} buf * @returns {IdentityKeyPair} */ static deserialise(buf) { TypeUtil.assert_is_instance(ArrayBuffer, buf); const d = new CBOR.Decoder(buf); return IdentityKeyPair.decode(d); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(3); e.u8(0); e.u8(this.version); e.u8(1); this.secret_key.encode(e); e.u8(2); return this.public_key.encode(e); } /** * @param {!CBOR.Decoder} d * @returns {IdentityKeyPair} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); const self = ClassUtil.new_instance(IdentityKeyPair); const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: self.version = d.u8(); break; case 1: self.secret_key = SecretKey.decode(d); break; case 2: self.public_key = IdentityKey.decode(d); break; default: d.skip(); } } TypeUtil.assert_is_integer(self.version); TypeUtil.assert_is_instance(SecretKey, self.secret_key); TypeUtil.assert_is_instance(IdentityKey, self.public_key); return self; } } module.exports = IdentityKeyPair; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const DecodeError = __webpack_require__(19); /** @module message */ /** * @class Message * @throws {DontCallConstructor} */ class Message { constructor() { throw new DontCallConstructor(this); } /** @returns {ArrayBuffer} */ serialise() { const e = new CBOR.Encoder(); if (this instanceof HeaderMessage) { e.u8(1); } else if (this instanceof PreKeyMessage) { e.u8(2); } else { throw new TypeError('Unexpected message type', 9); } this.encode(e); return e.get_buffer(); } /** * @param {!ArrayBuffer} buf * @returns {message.HeaderMessage|message.PreKeyMessage} */ static deserialise(buf) { TypeUtil.assert_is_instance(ArrayBuffer, buf); const d = new CBOR.Decoder(buf); switch (d.u8()) { case 1: return HeaderMessage.decode(d); case 2: return PreKeyMessage.decode(d); default: throw new DecodeError.InvalidType('Unrecognised message type', DecodeError.CODE.CASE_302); } } } module.exports = Message; // these require lines have to come after the Message definition because otherwise // it creates a circular dependency with the message subtypes const HeaderMessage = __webpack_require__(9); const PreKeyMessage = __webpack_require__(13); /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const IdentityKey = __webpack_require__(8); const PublicKey = __webpack_require__(4); const HeaderMessage = __webpack_require__(9); const Message = __webpack_require__(12); /** @module message */ /** * @extends Message * @throws {DontCallConstructor} */ class PreKeyMessage extends Message { constructor() { super(); throw new DontCallConstructor(this); } /** * @param {!number} prekey_id * @param {!keys.PublicKey} base_key * @param {!keys.IdentityKey} identity_key * @param {!message.HeaderMessage} message * @returns {PreKeyMessage} */ static new(prekey_id, base_key, identity_key, message) { TypeUtil.assert_is_integer(prekey_id); TypeUtil.assert_is_instance(PublicKey, base_key); TypeUtil.assert_is_instance(IdentityKey, identity_key); TypeUtil.assert_is_instance(HeaderMessage, message); const pkm = ClassUtil.new_instance(PreKeyMessage); pkm.prekey_id = prekey_id; pkm.base_key = base_key; pkm.identity_key = identity_key; pkm.message = message; Object.freeze(pkm); return pkm; } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(4); e.u8(0); e.u16(this.prekey_id); e.u8(1); this.base_key.encode(e); e.u8(2); this.identity_key.encode(e); e.u8(3); return this.message.encode(e); } /** * @param {!CBOR.Decoder} d * @returns {PreKeyMessage} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); let prekey_id = null; let base_key = null; let identity_key = null; let message = null; const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: prekey_id = d.u16(); break; case 1: base_key = PublicKey.decode(d); break; case 2: identity_key = IdentityKey.decode(d); break; case 3: message = HeaderMessage.decode(d); break; default: d.skip(); } } // checks for missing variables happens in constructor return PreKeyMessage.new(prekey_id, base_key, identity_key, message); } } module.exports = PreKeyMessage; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const MacKey = __webpack_require__(15); const Message = __webpack_require__(12); /** @module message */ /** * @class Envelope * @throws {DontCallConstructor} */ class Envelope { constructor() { throw new DontCallConstructor(this); } /** * @param {!derived.MacKey} mac_key MacKey generated by derived secrets * @param {!message.Message} message * @returns {Envelope} */ static new(mac_key, message) { TypeUtil.assert_is_instance(MacKey, mac_key); TypeUtil.assert_is_instance(Message, message); const serialized_message = new Uint8Array(message.serialise()); const env = ClassUtil.new_instance(Envelope); env.version = 1; env.mac = mac_key.sign(serialized_message); env.message = message; env._message_enc = serialized_message; Object.freeze(env); return env; } /** * @param {!derived.MacKey} mac_key The remote party's MacKey * @returns {boolean} */ verify(mac_key) { TypeUtil.assert_is_instance(MacKey, mac_key); return mac_key.verify(this.mac, this._message_enc); } /** @returns {ArrayBuffer} - The serialized message envelope */ serialise() { const e = new CBOR.Encoder(); this.encode(e); return e.get_buffer(); } /** * @param {!ArrayBuffer} buf * @returns {Envelope} */ static deserialise(buf) { TypeUtil.assert_is_instance(ArrayBuffer, buf); const d = new CBOR.Decoder(buf); return Envelope.decode(d); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(3); e.u8(0); e.u8(this.version); e.u8(1); e.object(1); e.u8(0); e.bytes(this.mac); e.u8(2); return e.bytes(this._message_enc); } /** * @param {!CBOR.Decoder} d * @returns {Envelope} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); const env = ClassUtil.new_instance(Envelope); const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: { env.version = d.u8(); break; } case 1: { const nprops_mac = d.object(); for (let j = 0; j <= nprops_mac - 1; j++) { switch (d.u8()) { case 0: env.mac = new Uint8Array(d.bytes()); break; default: d.skip(); } } break; } case 2: { env._message_enc = new Uint8Array(d.bytes()); break; } default: { d.skip(); } } } TypeUtil.assert_is_integer(env.version); TypeUtil.assert_is_instance(Uint8Array, env.mac); env.message = Message.deserialise(env._message_enc.buffer); Object.freeze(env); return env; } } module.exports = Envelope; /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const sodium = __webpack_require__(5); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); /** @module derived */ /** * @class MacKey * @throws {DontCallConstructor} */ class MacKey { constructor() { throw new DontCallConstructor(this); } /** * @param {!Uint8Array} key - Mac Key in byte array format generated by derived secrets * @returns {MacKey} - `this` */ static new(key) { TypeUtil.assert_is_instance(Uint8Array, key); const mk = ClassUtil.new_instance(MacKey); /** @type {Uint8Array} */ mk.key = key; return mk; } /** * Hash-based message authentication code * @param {!(string|Uint8Array)} msg * @returns {Uint8Array} */ sign(msg) { return sodium.crypto_auth_hmacsha256(msg, this.key); } /** * Verifies the signature of a given message by resigning it. * @param {!Uint8Array} signature Mac signature (HMAC) which needs to get verified * @param {!Uint8Array} msg Unsigned message * @returns {boolean} */ verify(signature, msg) { return sodium.crypto_auth_hmacsha256_verify(signature, msg, this.key); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(1); e.u8(0); return e.bytes(this.key); } /** * @param {!CBOR.Decoder} d * @returns {MacKey} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); let key_bytes = null; const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: key_bytes = new Uint8Array(d.bytes()); break; default: d.skip(); } } return MacKey.new(key_bytes); } } module.exports = MacKey; /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const sodium = __webpack_require__(5); /** @module util */ const MemoryUtil = { /** * @param {!(Uint8Array|ArrayBuffer|Object)} object * @returns {void} */ zeroize(object) { if (object instanceof Uint8Array) { sodium.memzero(object); } else if (object instanceof ArrayBuffer) { sodium.memzero(new Uint8Array(object)); } else if (typeof object === 'object') { Object.keys(object).map((key) => object[key]).forEach((val) => this.zeroize(val)); } }, }; module.exports = MemoryUtil; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const sodium = __webpack_require__(5); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); /** @module derived */ /** * @class HeadKey * @throws {DontCallConstructor} */ class HeadKey { constructor() { throw new DontCallConstructor(this); } /** * @param {!Uint8Array} key * @returns {HeadKey} - `this` */ static new(key) { TypeUtil.assert_is_instance(Uint8Array, key); const hk = ClassUtil.new_instance(HeadKey); /** @type {Uint8Array} */ hk.key = key; return hk; } /** * @param {!number} idx * @returns {Uint8Array} */ static index_as_nonce(idx) { const nonce = new ArrayBuffer(8); new DataView(nonce).setUint32(0, idx); return new Uint8Array(nonce); } /** * @param {!ArrayBuffer} header - The serialized header to encrypt * @param {!Uint8Array} nonce * @returns {Uint8Array} - Encrypted payload */ encrypt(header, nonce) { header = new Uint8Array(header); return sodium.crypto_stream_chacha20_xor(header, nonce, this.key, 'uint8array'); } /** * @param {!Uint8Array} encrypted_header * @param {!Uint8Array} nonce * @returns {Uint8Array} */ decrypt(encrypted_header, nonce) { return this.encrypt(encrypted_header, nonce); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(1); e.u8(0); return e.bytes(this.key); } /** * @param {!CBOR.Encoder} d * @returns {HeadKey} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); let key_bytes = null; const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: key_bytes = new Uint8Array(d.bytes()); break; default: d.skip(); } } return HeadKey.new(key_bytes); } } module.exports = HeadKey; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const CBOR = __webpack_require__(2); const ClassUtil = __webpack_require__(3); const DontCallConstructor = __webpack_require__(0); const TypeUtil = __webpack_require__(1); const DerivedSecrets = __webpack_require__(26); const MacKey = __webpack_require__(15); const MessageKeys = __webpack_require__(32); /** @module session */ /** * @class ChainKey * @throws {DontCallConstructor} */ class ChainKey { constructor() { throw new DontCallConstructor(this); } /** * @param {!derived.MacKey} key - Mac Key generated by derived secrets * @param {!number} counter * @returns {ChainKey} */ static from_mac_key(key, counter) { TypeUtil.assert_is_instance(MacKey, key); TypeUtil.assert_is_integer(counter); const ck = ClassUtil.new_instance(ChainKey); ck.key = key; ck.idx = counter; return ck; } /** @returns {ChainKey} */ next() { const ck = ClassUtil.new_instance(ChainKey); ck.key = MacKey.new(this.key.sign('1')); ck.idx = this.idx + 1; return ck; } /** @returns {session.MessageKeys} */ message_keys() { const base = this.key.sign('0'); const derived_secrets = DerivedSecrets.kdf_without_salt(base, 'hash_ratchet'); return MessageKeys.new(derived_secrets.cipher_key, derived_secrets.mac_key, this.idx); } /** * @param {!CBOR.Encoder} e * @returns {CBOR.Encoder} */ encode(e) { e.object(2); e.u8(0); this.key.encode(e); e.u8(1); return e.u32(this.idx); } /** * @param {!CBOR.Decoder} d * @returns {ChainKey} */ static decode(d) { TypeUtil.assert_is_instance(CBOR.Decoder, d); const self = ClassUtil.new_instance(ChainKey); const nprops = d.object(); for (let i = 0; i <= nprops - 1; i++) { switch (d.u8()) { case 0: self.key = MacKey.decode(d); break; case 1: self.idx = d.u32(); break; default: d.skip(); } } TypeUtil.assert_is_instance(MacKey, self.key); TypeUtil.assert_is_integer(self.idx); return self; } } module.exports = ChainKey; /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /* eslint no-unused-vars: "off" */ const ProteusError = __webpack_require__(6); /** @module errors */ /** * @extends ProteusError * @param {string} [message] * @param {string} [code] * @returns {string} */ class DecodeError extends ProteusError { constructor(message = 'Unknown decoding error', code = 3) { super(message, code); } static get CODE() { return { CASE_300: 300, CASE_301: 301, CASE_302: 302, CASE_303: 303, }; } } /** * @extends DecodeError * @param {string} [message] * @param {string} [code] * @returns {string} */ class InvalidType extends DecodeError { constructor(message = 'Invalid type', code) { super(message, code); } } /** * @extends DecodeError * @param {string} [message] * @param {string} [code] * @returns {string} */ class InvalidArrayLen extends DecodeError { constructor(message = 'Invalid array length', code) { super(message, code); } } /** * @extends DecodeError * @param {string} [message] * @param {string} [code] * @returns {string} */ class LocalIdentityChanged extends DecodeError { constructor(message = 'Local identity changed', code) { super(message, code); } } Object.assign(DecodeError, { InvalidType, InvalidArrayLen, LocalIdentityChanged, }); module.exports = ProteusError.DecodeError = DecodeError; /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* * Wire * Copyright (C) 2017 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const ProteusError = __webpack_require__(6); /** @module errors */ /** * @extends ProteusError * @param {string} [message] * @param {string} [code] * @returns {string} */ class InputError extends ProteusError { constructor(message = 'Invalid input', code = 4) { super(message, code); } static get CODE() { return { CASE_400: 400,