proteus-hd
Version:
Signal Protocol (with header encryption) implementation for JavaScript. Based on Proteus.js.
2,048 lines (1,715 loc) • 196 kB
JavaScript
/*! 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,