tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FxAccountsPairingChannel.sys.mjs (115421B)


      1 /*!
      2 * 
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      6 * 
      7 * The following bundle is from an external repository at github.com/mozilla/fxa-pairing-channel,
      8 * it implements a shared library for two javascript environments to create an encrypted and authenticated
      9 * communication channel by sharing a secret key and by relaying messages through a websocket server.
     10 * 
     11 * It is used by the Firefox Accounts pairing flow, with one side of the channel being web
     12 * content from https://accounts.firefox.com and the other side of the channel being chrome native code.
     13 * 
     14 * This uses the event-target-shim node library published under the MIT license:
     15 * https://github.com/mysticatea/event-target-shim/blob/master/LICENSE
     16 * 
     17 * Bundle generated from https://github.com/mozilla/fxa-pairing-channel.git. Hash:c8ec3119920b4ffa833b, Chunkhash:378a5f51445e7aa7630e.
     18 * 
     19 */
     20 
     21 // This header provides a little bit of plumbing to use `FxAccountsPairingChannel`
     22 // from Firefox browser code, hence the presence of these privileged browser APIs.
     23 // If you're trying to use this from ordinary web content you're in for a bad time.
     24 
     25 import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
     26 
     27 // We cannot use WebSocket from chrome code without a window,
     28 // see https://bugzilla.mozilla.org/show_bug.cgi?id=784686
     29 const browser = Services.appShell.createWindowlessBrowser(true);
     30 const {WebSocket} = browser.document.ownerGlobal;
     31 
     32 export var FxAccountsPairingChannel =
     33 /******/ (function(modules) { // webpackBootstrap
     34 /******/ 	// The module cache
     35 /******/ 	var installedModules = {};
     36 /******/
     37 /******/ 	// The require function
     38 /******/ 	function __webpack_require__(moduleId) {
     39 /******/
     40 /******/ 		// Check if module is in cache
     41 /******/ 		if(installedModules[moduleId]) {
     42 /******/ 			return installedModules[moduleId].exports;
     43 /******/ 		}
     44 /******/ 		// Create a new module (and put it into the cache)
     45 /******/ 		var module = installedModules[moduleId] = {
     46 /******/ 			i: moduleId,
     47 /******/ 			l: false,
     48 /******/ 			exports: {}
     49 /******/ 		};
     50 /******/
     51 /******/ 		// Execute the module function
     52 /******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
     53 /******/
     54 /******/ 		// Flag the module as loaded
     55 /******/ 		module.l = true;
     56 /******/
     57 /******/ 		// Return the exports of the module
     58 /******/ 		return module.exports;
     59 /******/ 	}
     60 /******/
     61 /******/
     62 /******/ 	// expose the modules object (__webpack_modules__)
     63 /******/ 	__webpack_require__.m = modules;
     64 /******/
     65 /******/ 	// expose the module cache
     66 /******/ 	__webpack_require__.c = installedModules;
     67 /******/
     68 /******/ 	// define getter function for harmony exports
     69 /******/ 	__webpack_require__.d = function(exports, name, getter) {
     70 /******/ 		if(!__webpack_require__.o(exports, name)) {
     71 /******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
     72 /******/ 		}
     73 /******/ 	};
     74 /******/
     75 /******/ 	// define __esModule on exports
     76 /******/ 	__webpack_require__.r = function(exports) {
     77 /******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
     78 /******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
     79 /******/ 		}
     80 /******/ 		Object.defineProperty(exports, '__esModule', { value: true });
     81 /******/ 	};
     82 /******/
     83 /******/ 	// create a fake namespace object
     84 /******/ 	// mode & 1: value is a module id, require it
     85 /******/ 	// mode & 2: merge all properties of value into the ns
     86 /******/ 	// mode & 4: return value when already ns object
     87 /******/ 	// mode & 8|1: behave like require
     88 /******/ 	__webpack_require__.t = function(value, mode) {
     89 /******/ 		if(mode & 1) value = __webpack_require__(value);
     90 /******/ 		if(mode & 8) return value;
     91 /******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
     92 /******/ 		var ns = Object.create(null);
     93 /******/ 		__webpack_require__.r(ns);
     94 /******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
     95 /******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
     96 /******/ 		return ns;
     97 /******/ 	};
     98 /******/
     99 /******/ 	// getDefaultExport function for compatibility with non-harmony modules
    100 /******/ 	__webpack_require__.n = function(module) {
    101 /******/ 		var getter = module && module.__esModule ?
    102 /******/ 			function getDefault() { return module['default']; } :
    103 /******/ 			function getModuleExports() { return module; };
    104 /******/ 		__webpack_require__.d(getter, 'a', getter);
    105 /******/ 		return getter;
    106 /******/ 	};
    107 /******/
    108 /******/ 	// Object.prototype.hasOwnProperty.call
    109 /******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
    110 /******/
    111 /******/ 	// __webpack_public_path__
    112 /******/ 	__webpack_require__.p = "";
    113 /******/
    114 /******/
    115 /******/ 	// Load entry module and return exports
    116 /******/ 	return __webpack_require__(__webpack_require__.s = 0);
    117 /******/ })
    118 /************************************************************************/
    119 /******/ ([
    120 /* 0 */
    121 /***/ (function(module, __webpack_exports__, __webpack_require__) {
    122 
    123 "use strict";
    124 // ESM COMPAT FLAG
    125 __webpack_require__.r(__webpack_exports__);
    126 
    127 // EXPORTS
    128 __webpack_require__.d(__webpack_exports__, "PairingChannel", function() { return /* binding */ src_PairingChannel; });
    129 __webpack_require__.d(__webpack_exports__, "base64urlToBytes", function() { return /* reexport */ base64urlToBytes; });
    130 __webpack_require__.d(__webpack_exports__, "bytesToBase64url", function() { return /* reexport */ bytesToBase64url; });
    131 __webpack_require__.d(__webpack_exports__, "bytesToHex", function() { return /* reexport */ bytesToHex; });
    132 __webpack_require__.d(__webpack_exports__, "bytesToUtf8", function() { return /* reexport */ bytesToUtf8; });
    133 __webpack_require__.d(__webpack_exports__, "hexToBytes", function() { return /* reexport */ hexToBytes; });
    134 __webpack_require__.d(__webpack_exports__, "TLSCloseNotify", function() { return /* reexport */ TLSCloseNotify; });
    135 __webpack_require__.d(__webpack_exports__, "TLSError", function() { return /* reexport */ TLSError; });
    136 __webpack_require__.d(__webpack_exports__, "utf8ToBytes", function() { return /* reexport */ utf8ToBytes; });
    137 __webpack_require__.d(__webpack_exports__, "_internals", function() { return /* binding */ _internals; });
    138 
    139 // CONCATENATED MODULE: ./src/alerts.js
    140 /* This Source Code Form is subject to the terms of the Mozilla Public
    141 * License, v. 2.0. If a copy of the MPL was not distributed with this
    142 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    143 
    144 /* eslint-disable sorting/sort-object-props */
    145 const ALERT_LEVEL = {
    146  WARNING: 1,
    147  FATAL: 2
    148 };
    149 
    150 const ALERT_DESCRIPTION = {
    151  CLOSE_NOTIFY: 0,
    152  UNEXPECTED_MESSAGE: 10,
    153  BAD_RECORD_MAC: 20,
    154  RECORD_OVERFLOW: 22,
    155  HANDSHAKE_FAILURE: 40,
    156  ILLEGAL_PARAMETER: 47,
    157  DECODE_ERROR: 50,
    158  DECRYPT_ERROR: 51,
    159  PROTOCOL_VERSION: 70,
    160  INTERNAL_ERROR: 80,
    161  MISSING_EXTENSION: 109,
    162  UNSUPPORTED_EXTENSION: 110,
    163  UNKNOWN_PSK_IDENTITY: 115,
    164  NO_APPLICATION_PROTOCOL: 120,
    165 };
    166 /* eslint-enable sorting/sort-object-props */
    167 
    168 function alertTypeToName(type) {
    169  for (const name in ALERT_DESCRIPTION) {
    170    if (ALERT_DESCRIPTION[name] === type) {
    171      return `${name} (${type})`;
    172    }
    173  }
    174  return `UNKNOWN (${type})`;
    175 }
    176 
    177 class TLSAlert extends Error {
    178  constructor(description, level) {
    179    super(`TLS Alert: ${alertTypeToName(description)}`);
    180    this.description = description;
    181    this.level = level;
    182  }
    183 
    184  static fromBytes(bytes) {
    185    if (bytes.byteLength !== 2) {
    186      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    187    }
    188    switch (bytes[1]) {
    189      case ALERT_DESCRIPTION.CLOSE_NOTIFY:
    190        if (bytes[0] !== ALERT_LEVEL.WARNING) {
    191          // Close notifications should be fatal.
    192          throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
    193        }
    194        return new TLSCloseNotify();
    195      default:
    196        return new TLSError(bytes[1]);
    197    }
    198  }
    199 
    200  toBytes() {
    201    return new Uint8Array([this.level, this.description]);
    202  }
    203 }
    204 
    205 class TLSCloseNotify extends TLSAlert {
    206  constructor() {
    207    super(ALERT_DESCRIPTION.CLOSE_NOTIFY, ALERT_LEVEL.WARNING);
    208  }
    209 }
    210 
    211 class TLSError extends TLSAlert {
    212  constructor(description = ALERT_DESCRIPTION.INTERNAL_ERROR) {
    213    super(description, ALERT_LEVEL.FATAL);
    214  }
    215 }
    216 
    217 // CONCATENATED MODULE: ./src/utils.js
    218 /* This Source Code Form is subject to the terms of the Mozilla Public
    219 * License, v. 2.0. If a copy of the MPL was not distributed with this
    220 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    221 
    222 
    223 
    224 //
    225 // Various low-level utility functions.
    226 //
    227 // These are mostly conveniences for working with Uint8Arrays as
    228 // the primitive "bytes" type.
    229 //
    230 
    231 const UTF8_ENCODER = new TextEncoder();
    232 const UTF8_DECODER = new TextDecoder();
    233 
    234 function noop() {}
    235 
    236 function assert(cond, msg) {
    237  if (! cond) {
    238    throw new Error('assert failed: ' + msg);
    239  }
    240 }
    241 
    242 function assertIsBytes(value, msg = 'value must be a Uint8Array') {
    243  // Using `value instanceof Uint8Array` seems to fail in Firefox chrome code
    244  // for inscrutable reasons, so we do a less direct check.
    245  assert(ArrayBuffer.isView(value), msg);
    246  assert(value.BYTES_PER_ELEMENT === 1, msg);
    247  return value;
    248 }
    249 
    250 const EMPTY = new Uint8Array(0);
    251 
    252 function zeros(n) {
    253  return new Uint8Array(n);
    254 }
    255 
    256 function arrayToBytes(value) {
    257  return new Uint8Array(value);
    258 }
    259 
    260 function bytesToHex(bytes) {
    261  return Array.prototype.map.call(bytes, byte => {
    262    let s = byte.toString(16);
    263    if (s.length === 1) {
    264      s = '0' + s;
    265    }
    266    return s;
    267  }).join('');
    268 }
    269 
    270 function hexToBytes(hexstr) {
    271  assert(hexstr.length % 2 === 0, 'hexstr.length must be even');
    272  return new Uint8Array(Array.prototype.map.call(hexstr, (c, n) => {
    273    if (n % 2 === 1) {
    274      return hexstr[n - 1] + c;
    275    } else {
    276      return '';
    277    }
    278  }).filter(s => {
    279    return !! s;
    280  }).map(s => {
    281    return parseInt(s, 16);
    282  }));
    283 }
    284 
    285 function bytesToUtf8(bytes) {
    286  return UTF8_DECODER.decode(bytes);
    287 }
    288 
    289 function utf8ToBytes(str) {
    290  return UTF8_ENCODER.encode(str);
    291 }
    292 
    293 function bytesToBase64url(bytes) {
    294  // XXX TODO: try to use something constant-time, in case calling code
    295  // uses it to encode secrets?
    296  const charCodes = String.fromCharCode.apply(String, bytes);
    297  return btoa(charCodes).replace(/\+/g, '-').replace(/\//g, '_');
    298 }
    299 
    300 function base64urlToBytes(str) {
    301  // XXX TODO: try to use something constant-time, in case calling code
    302  // uses it to decode secrets?
    303  str = atob(str.replace(/-/g, '+').replace(/_/g, '/'));
    304  const bytes = new Uint8Array(str.length);
    305  for (let i = 0; i < str.length; i++) {
    306    bytes[i] = str.charCodeAt(i);
    307  }
    308  return bytes;
    309 }
    310 
    311 function bytesAreEqual(v1, v2) {
    312  assertIsBytes(v1);
    313  assertIsBytes(v2);
    314  if (v1.length !== v2.length) {
    315    return false;
    316  }
    317  for (let i = 0; i < v1.length; i++) {
    318    if (v1[i] !== v2[i]) {
    319      return false;
    320    }
    321  }
    322  return true;
    323 }
    324 
    325 // The `BufferReader` and `BufferWriter` classes are helpers for dealing with the
    326 // binary struct format that's used for various TLS message.  Think of them as a
    327 // buffer with a pointer to the "current position" and a bunch of helper methods
    328 // to read/write structured data and advance said pointer.
    329 
    330 class utils_BufferWithPointer {
    331  constructor(buf) {
    332    this._buffer = buf;
    333    this._dataview = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
    334    this._pos = 0;
    335  }
    336 
    337  length() {
    338    return this._buffer.byteLength;
    339  }
    340 
    341  tell() {
    342    return this._pos;
    343  }
    344 
    345  seek(pos) {
    346    if (pos < 0) {
    347      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    348    }
    349    if (pos > this.length()) {
    350      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    351    }
    352    this._pos = pos;
    353  }
    354 
    355  incr(offset) {
    356    this.seek(this._pos + offset);
    357  }
    358 }
    359 
    360 // The `BufferReader` class helps you read structured data from a byte array.
    361 // It offers methods for reading both primitive values, and the variable-length
    362 // vector structures defined in https://tools.ietf.org/html/rfc8446#section-3.4.
    363 //
    364 // Such vectors are represented as a length followed by the concatenated
    365 // bytes of each item, and the size of the length field is determined by
    366 // the maximum allowed number of bytes in the vector.  For example
    367 // to read a vector that may contain up to 65535 bytes, use `readVector16`.
    368 //
    369 // To read a variable-length vector of between 1 and 100 uint16 values,
    370 // defined in the RFC like this:
    371 //
    372 //    uint16 items<2..200>;
    373 //
    374 // You would do something like this:
    375 //
    376 //    const items = []
    377 //    buf.readVector8(buf => {
    378 //      items.push(buf.readUint16())
    379 //    })
    380 //
    381 // The various `read` will throw `DECODE_ERROR` if you attempt to read path
    382 // the end of the buffer, or past the end of a variable-length list.
    383 //
    384 class utils_BufferReader extends utils_BufferWithPointer {
    385 
    386  hasMoreBytes() {
    387    return this.tell() < this.length();
    388  }
    389 
    390  readBytes(length) {
    391    // This avoids copies by returning a view onto the existing buffer.
    392    const start = this._buffer.byteOffset + this.tell();
    393    this.incr(length);
    394    return new Uint8Array(this._buffer.buffer, start, length);
    395  }
    396 
    397  _rangeErrorToAlert(cb) {
    398    try {
    399      return cb(this);
    400    } catch (err) {
    401      if (err instanceof RangeError) {
    402        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    403      }
    404      throw err;
    405    }
    406  }
    407 
    408  readUint8() {
    409    return this._rangeErrorToAlert(() => {
    410      const n = this._dataview.getUint8(this._pos);
    411      this.incr(1);
    412      return n;
    413    });
    414  }
    415 
    416  readUint16() {
    417    return this._rangeErrorToAlert(() => {
    418      const n = this._dataview.getUint16(this._pos);
    419      this.incr(2);
    420      return n;
    421    });
    422  }
    423 
    424  readUint24() {
    425    return this._rangeErrorToAlert(() => {
    426      let n = this._dataview.getUint16(this._pos);
    427      n = (n << 8) | this._dataview.getUint8(this._pos + 2);
    428      this.incr(3);
    429      return n;
    430    });
    431  }
    432 
    433  readUint32() {
    434    return this._rangeErrorToAlert(() => {
    435      const n = this._dataview.getUint32(this._pos);
    436      this.incr(4);
    437      return n;
    438    });
    439  }
    440 
    441  _readVector(length, cb) {
    442    const contentsBuf = new utils_BufferReader(this.readBytes(length));
    443    const expectedEnd = this.tell();
    444    // Keep calling the callback until we've consumed the expected number of bytes.
    445    let n = 0;
    446    while (contentsBuf.hasMoreBytes()) {
    447      const prevPos = contentsBuf.tell();
    448      cb(contentsBuf, n);
    449      // Check that the callback made forward progress, otherwise we'll infinite loop.
    450      if (contentsBuf.tell() <= prevPos) {
    451        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    452      }
    453      n += 1;
    454    }
    455    // Check that the callback correctly consumed the vector's entire contents.
    456    if (this.tell() !== expectedEnd) {
    457      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    458    }
    459  }
    460 
    461  readVector8(cb) {
    462    const length = this.readUint8();
    463    return this._readVector(length, cb);
    464  }
    465 
    466  readVector16(cb) {
    467    const length = this.readUint16();
    468    return this._readVector(length, cb);
    469  }
    470 
    471  readVector24(cb) {
    472    const length = this.readUint24();
    473    return this._readVector(length, cb);
    474  }
    475 
    476  readVectorBytes8() {
    477    return this.readBytes(this.readUint8());
    478  }
    479 
    480  readVectorBytes16() {
    481    return this.readBytes(this.readUint16());
    482  }
    483 
    484  readVectorBytes24() {
    485    return this.readBytes(this.readUint24());
    486  }
    487 }
    488 
    489 
    490 class utils_BufferWriter extends utils_BufferWithPointer {
    491  constructor(size = 1024) {
    492    super(new Uint8Array(size));
    493  }
    494 
    495  _maybeGrow(n) {
    496    const curSize = this._buffer.byteLength;
    497    const newPos = this._pos + n;
    498    const shortfall = newPos - curSize;
    499    if (shortfall > 0) {
    500      // Classic grow-by-doubling, up to 4kB max increment.
    501      // This formula was not arrived at by any particular science.
    502      const incr = Math.min(curSize, 4 * 1024);
    503      const newbuf = new Uint8Array(curSize + Math.ceil(shortfall / incr) * incr);
    504      newbuf.set(this._buffer, 0);
    505      this._buffer = newbuf;
    506      this._dataview = new DataView(newbuf.buffer, newbuf.byteOffset, newbuf.byteLength);
    507    }
    508  }
    509 
    510  slice(start = 0, end = this.tell()) {
    511    if (end < 0) {
    512      end = this.tell() + end;
    513    }
    514    if (start < 0) {
    515      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    516    }
    517    if (end < 0) {
    518      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    519    }
    520    if (end > this.length()) {
    521      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    522    }
    523    return this._buffer.slice(start, end);
    524  }
    525 
    526  flush() {
    527    const slice = this.slice();
    528    this.seek(0);
    529    return slice;
    530  }
    531 
    532  writeBytes(data) {
    533    this._maybeGrow(data.byteLength);
    534    this._buffer.set(data, this.tell());
    535    this.incr(data.byteLength);
    536  }
    537 
    538  writeUint8(n) {
    539    this._maybeGrow(1);
    540    this._dataview.setUint8(this._pos, n);
    541    this.incr(1);
    542  }
    543 
    544  writeUint16(n) {
    545    this._maybeGrow(2);
    546    this._dataview.setUint16(this._pos, n);
    547    this.incr(2);
    548  }
    549 
    550  writeUint24(n) {
    551    this._maybeGrow(3);
    552    this._dataview.setUint16(this._pos, n >> 8);
    553    this._dataview.setUint8(this._pos + 2, n & 0xFF);
    554    this.incr(3);
    555  }
    556 
    557  writeUint32(n) {
    558    this._maybeGrow(4);
    559    this._dataview.setUint32(this._pos, n);
    560    this.incr(4);
    561  }
    562 
    563  // These are helpers for writing the variable-length vector structure
    564  // defined in https://tools.ietf.org/html/rfc8446#section-3.4.
    565  //
    566  // Such vectors are represented as a length followed by the concatenated
    567  // bytes of each item, and the size of the length field is determined by
    568  // the maximum allowed size of the vector.  For example to write a vector
    569  // that may contain up to 65535 bytes, use `writeVector16`.
    570  //
    571  // To write a variable-length vector of between 1 and 100 uint16 values,
    572  // defined in the RFC like this:
    573  //
    574  //    uint16 items<2..200>;
    575  //
    576  // You would do something like this:
    577  //
    578  //    buf.writeVector8(buf => {
    579  //      for (let item of items) {
    580  //          buf.writeUint16(item)
    581  //      }
    582  //    })
    583  //
    584  // The helper will automatically take care of writing the appropriate
    585  // length field once the callback completes.
    586 
    587  _writeVector(maxLength, writeLength, cb) {
    588    // Initially, write the length field as zero.
    589    const lengthPos = this.tell();
    590    writeLength(0);
    591    // Call the callback to write the vector items.
    592    const bodyPos = this.tell();
    593    cb(this);
    594    const length = this.tell() - bodyPos;
    595    if (length >= maxLength) {
    596      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    597    }
    598    // Backfill the actual length field.
    599    this.seek(lengthPos);
    600    writeLength(length);
    601    this.incr(length);
    602    return length;
    603  }
    604 
    605  writeVector8(cb) {
    606    return this._writeVector(Math.pow(2, 8), len => this.writeUint8(len), cb);
    607  }
    608 
    609  writeVector16(cb) {
    610    return this._writeVector(Math.pow(2, 16), len => this.writeUint16(len), cb);
    611  }
    612 
    613  writeVector24(cb) {
    614    return this._writeVector(Math.pow(2, 24), len => this.writeUint24(len), cb);
    615  }
    616 
    617  writeVectorBytes8(bytes) {
    618    return this.writeVector8(buf => {
    619      buf.writeBytes(bytes);
    620    });
    621  }
    622 
    623  writeVectorBytes16(bytes) {
    624    return this.writeVector16(buf => {
    625      buf.writeBytes(bytes);
    626    });
    627  }
    628 
    629  writeVectorBytes24(bytes) {
    630    return this.writeVector24(buf => {
    631      buf.writeBytes(bytes);
    632    });
    633  }
    634 }
    635 
    636 // CONCATENATED MODULE: ./src/crypto.js
    637 /* This Source Code Form is subject to the terms of the Mozilla Public
    638 * License, v. 2.0. If a copy of the MPL was not distributed with this
    639 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    640 
    641 //
    642 // Low-level crypto primitives.
    643 //
    644 // This file implements the AEAD encrypt/decrypt and hashing routines
    645 // for the TLS_AES_128_GCM_SHA256 ciphersuite. They are (thankfully)
    646 // fairly light-weight wrappers around what's available via the WebCrypto
    647 // API.
    648 //
    649 
    650 
    651 
    652 
    653 const AEAD_SIZE_INFLATION = 16;
    654 const KEY_LENGTH = 16;
    655 const IV_LENGTH = 12;
    656 const HASH_LENGTH = 32;
    657 
    658 async function prepareKey(key, mode) {
    659  return crypto.subtle.importKey('raw', key, { name: 'AES-GCM' }, false, [mode]);
    660 }
    661 
    662 async function encrypt(key, iv, plaintext, additionalData) {
    663  const ciphertext = await crypto.subtle.encrypt({
    664    additionalData,
    665    iv,
    666    name: 'AES-GCM',
    667    tagLength: AEAD_SIZE_INFLATION * 8
    668  }, key, plaintext);
    669  return new Uint8Array(ciphertext);
    670 }
    671 
    672 async function decrypt(key, iv, ciphertext, additionalData) {
    673  try {
    674    const plaintext = await crypto.subtle.decrypt({
    675      additionalData,
    676      iv,
    677      name: 'AES-GCM',
    678      tagLength: AEAD_SIZE_INFLATION * 8
    679    }, key, ciphertext);
    680    return new Uint8Array(plaintext);
    681  } catch (err) {
    682    // Yes, we really do throw 'decrypt_error' when failing to verify a HMAC,
    683    // and a 'bad_record_mac' error when failing to decrypt.
    684    throw new TLSError(ALERT_DESCRIPTION.BAD_RECORD_MAC);
    685  }
    686 }
    687 
    688 async function hash(message) {
    689  return new Uint8Array(await crypto.subtle.digest({ name: 'SHA-256' }, message));
    690 }
    691 
    692 async function hmac(keyBytes, message) {
    693  const key = await crypto.subtle.importKey('raw', keyBytes, {
    694    hash: { name: 'SHA-256' },
    695    name: 'HMAC',
    696  }, false, ['sign']);
    697  const sig = await crypto.subtle.sign({ name: 'HMAC' }, key, message);
    698  return new Uint8Array(sig);
    699 }
    700 
    701 async function verifyHmac(keyBytes, signature, message) {
    702  const key = await crypto.subtle.importKey('raw', keyBytes, {
    703    hash: { name: 'SHA-256' },
    704    name: 'HMAC',
    705  }, false, ['verify']);
    706  if (! (await crypto.subtle.verify({ name: 'HMAC' }, key, signature, message))) {
    707    // Yes, we really do throw 'decrypt_error' when failing to verify a HMAC,
    708    // and a 'bad_record_mac' error when failing to decrypt.
    709    throw new TLSError(ALERT_DESCRIPTION.DECRYPT_ERROR);
    710  }
    711 }
    712 
    713 async function hkdfExtract(salt, ikm) {
    714  // Ref https://tools.ietf.org/html/rfc5869#section-2.2
    715  return await hmac(salt, ikm);
    716 }
    717 
    718 async function hkdfExpand(prk, info, length) {
    719  // Ref https://tools.ietf.org/html/rfc5869#section-2.3
    720  const N = Math.ceil(length / HASH_LENGTH);
    721  if (N <= 0) {
    722    throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    723  }
    724  if (N >= 255) {
    725    throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    726  }
    727  const input = new utils_BufferWriter();
    728  const output = new utils_BufferWriter();
    729  let T = new Uint8Array(0);
    730  for (let i = 1; i <= N; i++) {
    731    input.writeBytes(T);
    732    input.writeBytes(info);
    733    input.writeUint8(i);
    734    T = await hmac(prk, input.flush());
    735    output.writeBytes(T);
    736  }
    737  return output.slice(0, length);
    738 }
    739 
    740 async function hkdfExpandLabel(secret, label, context, length) {
    741  //  struct {
    742  //    uint16 length = Length;
    743  //    opaque label < 7..255 > = "tls13 " + Label;
    744  //    opaque context < 0..255 > = Context;
    745  //  } HkdfLabel;
    746  const hkdfLabel = new utils_BufferWriter();
    747  hkdfLabel.writeUint16(length);
    748  hkdfLabel.writeVectorBytes8(utf8ToBytes('tls13 ' + label));
    749  hkdfLabel.writeVectorBytes8(context);
    750  return hkdfExpand(secret, hkdfLabel.flush(), length);
    751 }
    752 
    753 async function getRandomBytes(size) {
    754  const bytes = new Uint8Array(size);
    755  crypto.getRandomValues(bytes);
    756  return bytes;
    757 }
    758 
    759 // CONCATENATED MODULE: ./src/extensions.js
    760 /* This Source Code Form is subject to the terms of the Mozilla Public
    761 * License, v. 2.0. If a copy of the MPL was not distributed with this
    762 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    763 
    764 //
    765 // Extension parsing.
    766 //
    767 // This file contains some helpers for reading/writing the various kinds
    768 // of Extension that might appear in a HandshakeMessage.
    769 //
    770 // "Extensions" are how TLS signals the presence of particular bits of optional
    771 // functionality in the protocol. Lots of parts of TLS1.3 that don't seem like
    772 // they're optional are implemented in terms of an extension, IIUC because that's
    773 // what was needed for a clean deployment in amongst earlier versions of the protocol.
    774 //
    775 
    776 
    777 
    778 
    779 
    780 /* eslint-disable sorting/sort-object-props */
    781 const EXTENSION_TYPE = {
    782  PRE_SHARED_KEY: 41,
    783  SUPPORTED_VERSIONS: 43,
    784  PSK_KEY_EXCHANGE_MODES: 45,
    785 };
    786 /* eslint-enable sorting/sort-object-props */
    787 
    788 // Base class for generic reading/writing of extensions,
    789 // which are all uniformly formatted as:
    790 //
    791 //   struct {
    792 //     ExtensionType extension_type;
    793 //     opaque extension_data<0..2^16-1>;
    794 //   } Extension;
    795 //
    796 // Extensions always appear inside of a handshake message,
    797 // and their internal structure may differ based on the
    798 // type of that message.
    799 
    800 class extensions_Extension {
    801 
    802  get TYPE_TAG() {
    803    throw new Error('not implemented');
    804  }
    805 
    806  static read(messageType, buf) {
    807    const type = buf.readUint16();
    808    let ext = {
    809      TYPE_TAG: type,
    810    };
    811    buf.readVector16(buf => {
    812      switch (type) {
    813        case EXTENSION_TYPE.PRE_SHARED_KEY:
    814          ext = extensions_PreSharedKeyExtension._read(messageType, buf);
    815          break;
    816        case EXTENSION_TYPE.SUPPORTED_VERSIONS:
    817          ext = extensions_SupportedVersionsExtension._read(messageType, buf);
    818          break;
    819        case EXTENSION_TYPE.PSK_KEY_EXCHANGE_MODES:
    820          ext = extensions_PskKeyExchangeModesExtension._read(messageType, buf);
    821          break;
    822        default:
    823          // Skip over unrecognised extensions.
    824          buf.incr(buf.length());
    825      }
    826      if (buf.hasMoreBytes()) {
    827        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
    828      }
    829    });
    830    return ext;
    831  }
    832 
    833  write(messageType, buf) {
    834    buf.writeUint16(this.TYPE_TAG);
    835    buf.writeVector16(buf => {
    836      this._write(messageType, buf);
    837    });
    838  }
    839 
    840  static _read(messageType, buf) {
    841    throw new Error('not implemented');
    842  }
    843 
    844  static _write(messageType, buf) {
    845    throw new Error('not implemented');
    846  }
    847 }
    848 
    849 // The PreSharedKey extension:
    850 //
    851 //  struct {
    852 //    opaque identity<1..2^16-1>;
    853 //    uint32 obfuscated_ticket_age;
    854 //  } PskIdentity;
    855 //  opaque PskBinderEntry<32..255>;
    856 //  struct {
    857 //    PskIdentity identities<7..2^16-1>;
    858 //    PskBinderEntry binders<33..2^16-1>;
    859 //  } OfferedPsks;
    860 //  struct {
    861 //    select(Handshake.msg_type) {
    862 //      case client_hello: OfferedPsks;
    863 //      case server_hello: uint16 selected_identity;
    864 //    };
    865 //  } PreSharedKeyExtension;
    866 
    867 class extensions_PreSharedKeyExtension extends extensions_Extension {
    868  constructor(identities, binders, selectedIdentity) {
    869    super();
    870    this.identities = identities;
    871    this.binders = binders;
    872    this.selectedIdentity = selectedIdentity;
    873  }
    874 
    875  get TYPE_TAG() {
    876    return EXTENSION_TYPE.PRE_SHARED_KEY;
    877  }
    878 
    879  static _read(messageType, buf) {
    880    let identities = null, binders = null, selectedIdentity = null;
    881    switch (messageType) {
    882      case HANDSHAKE_TYPE.CLIENT_HELLO:
    883        identities = []; binders = [];
    884        buf.readVector16(buf => {
    885          const identity = buf.readVectorBytes16();
    886          buf.readBytes(4); // Skip over the ticket age.
    887          identities.push(identity);
    888        });
    889        buf.readVector16(buf => {
    890          const binder = buf.readVectorBytes8();
    891          if (binder.byteLength < HASH_LENGTH) {
    892            throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
    893          }
    894          binders.push(binder);
    895        });
    896        if (identities.length !== binders.length) {
    897          throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
    898        }
    899        break;
    900      case HANDSHAKE_TYPE.SERVER_HELLO:
    901        selectedIdentity = buf.readUint16();
    902        break;
    903      default:
    904        throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
    905    }
    906    return new this(identities, binders, selectedIdentity);
    907  }
    908 
    909  _write(messageType, buf) {
    910    switch (messageType) {
    911      case HANDSHAKE_TYPE.CLIENT_HELLO:
    912        buf.writeVector16(buf => {
    913          this.identities.forEach(pskId => {
    914            buf.writeVectorBytes16(pskId);
    915            buf.writeUint32(0); // Zero for "tag age" field.
    916          });
    917        });
    918        buf.writeVector16(buf => {
    919          this.binders.forEach(pskBinder => {
    920            buf.writeVectorBytes8(pskBinder);
    921          });
    922        });
    923        break;
    924      case HANDSHAKE_TYPE.SERVER_HELLO:
    925        buf.writeUint16(this.selectedIdentity);
    926        break;
    927      default:
    928        throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    929    }
    930  }
    931 }
    932 
    933 
    934 // The SupportedVersions extension:
    935 //
    936 //  struct {
    937 //    select(Handshake.msg_type) {
    938 //      case client_hello:
    939 //        ProtocolVersion versions < 2..254 >;
    940 //      case server_hello:
    941 //        ProtocolVersion selected_version;
    942 //    };
    943 //  } SupportedVersions;
    944 
    945 class extensions_SupportedVersionsExtension extends extensions_Extension {
    946  constructor(versions, selectedVersion) {
    947    super();
    948    this.versions = versions;
    949    this.selectedVersion = selectedVersion;
    950  }
    951 
    952  get TYPE_TAG() {
    953    return EXTENSION_TYPE.SUPPORTED_VERSIONS;
    954  }
    955 
    956  static _read(messageType, buf) {
    957    let versions = null, selectedVersion = null;
    958    switch (messageType) {
    959      case HANDSHAKE_TYPE.CLIENT_HELLO:
    960        versions = [];
    961        buf.readVector8(buf => {
    962          versions.push(buf.readUint16());
    963        });
    964        break;
    965      case HANDSHAKE_TYPE.SERVER_HELLO:
    966        selectedVersion = buf.readUint16();
    967        break;
    968      default:
    969        throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
    970    }
    971    return new this(versions, selectedVersion);
    972  }
    973 
    974  _write(messageType, buf) {
    975    switch (messageType) {
    976      case HANDSHAKE_TYPE.CLIENT_HELLO:
    977        buf.writeVector8(buf => {
    978          this.versions.forEach(version => {
    979            buf.writeUint16(version);
    980          });
    981        });
    982        break;
    983      case HANDSHAKE_TYPE.SERVER_HELLO:
    984        buf.writeUint16(this.selectedVersion);
    985        break;
    986      default:
    987        throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
    988    }
    989  }
    990 }
    991 
    992 
    993 class extensions_PskKeyExchangeModesExtension extends extensions_Extension {
    994  constructor(modes) {
    995    super();
    996    this.modes = modes;
    997  }
    998 
    999  get TYPE_TAG() {
   1000    return EXTENSION_TYPE.PSK_KEY_EXCHANGE_MODES;
   1001  }
   1002 
   1003  static _read(messageType, buf) {
   1004    const modes = [];
   1005    switch (messageType) {
   1006      case HANDSHAKE_TYPE.CLIENT_HELLO:
   1007        buf.readVector8(buf => {
   1008          modes.push(buf.readUint8());
   1009        });
   1010        break;
   1011      default:
   1012        throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1013    }
   1014    return new this(modes);
   1015  }
   1016 
   1017  _write(messageType, buf) {
   1018    switch (messageType) {
   1019      case HANDSHAKE_TYPE.CLIENT_HELLO:
   1020        buf.writeVector8(buf => {
   1021          this.modes.forEach(mode => {
   1022            buf.writeUint8(mode);
   1023          });
   1024        });
   1025        break;
   1026      default:
   1027        throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1028    }
   1029  }
   1030 }
   1031 
   1032 // CONCATENATED MODULE: ./src/constants.js
   1033 /* This Source Code Form is subject to the terms of the Mozilla Public
   1034 * License, v. 2.0. If a copy of the MPL was not distributed with this
   1035 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   1036 
   1037 const VERSION_TLS_1_0 = 0x0301;
   1038 const VERSION_TLS_1_2 = 0x0303;
   1039 const VERSION_TLS_1_3 = 0x0304;
   1040 const TLS_AES_128_GCM_SHA256 = 0x1301;
   1041 const PSK_MODE_KE = 0;
   1042 
   1043 // CONCATENATED MODULE: ./src/messages.js
   1044 /* This Source Code Form is subject to the terms of the Mozilla Public
   1045 * License, v. 2.0. If a copy of the MPL was not distributed with this
   1046 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   1047 
   1048 //
   1049 // Message parsing.
   1050 //
   1051 // Herein we have code for reading and writing the various Handshake
   1052 // messages involved in the TLS protocol.
   1053 //
   1054 
   1055 
   1056 
   1057 
   1058 
   1059 
   1060 
   1061 /* eslint-disable sorting/sort-object-props */
   1062 const HANDSHAKE_TYPE = {
   1063  CLIENT_HELLO: 1,
   1064  SERVER_HELLO: 2,
   1065  NEW_SESSION_TICKET: 4,
   1066  ENCRYPTED_EXTENSIONS: 8,
   1067  FINISHED: 20,
   1068 };
   1069 /* eslint-enable sorting/sort-object-props */
   1070 
   1071 // Base class for generic reading/writing of handshake messages,
   1072 // which are all uniformly formatted as:
   1073 //
   1074 //  struct {
   1075 //    HandshakeType msg_type;    /* handshake type */
   1076 //    uint24 length;             /* bytes in message */
   1077 //    select(Handshake.msg_type) {
   1078 //        ... type specific cases here ...
   1079 //    };
   1080 //  } Handshake;
   1081 
   1082 class messages_HandshakeMessage {
   1083 
   1084  get TYPE_TAG() {
   1085    throw new Error('not implemented');
   1086  }
   1087 
   1088  static fromBytes(bytes) {
   1089    // Each handshake message has a type and length prefix, per
   1090    // https://tools.ietf.org/html/rfc8446#appendix-B.3
   1091    const buf = new utils_BufferReader(bytes);
   1092    const msg = this.read(buf);
   1093    if (buf.hasMoreBytes()) {
   1094      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   1095    }
   1096    return msg;
   1097  }
   1098 
   1099  toBytes() {
   1100    const buf = new utils_BufferWriter();
   1101    this.write(buf);
   1102    return buf.flush();
   1103  }
   1104 
   1105  static read(buf) {
   1106    const type = buf.readUint8();
   1107    let msg = null;
   1108    buf.readVector24(buf => {
   1109      switch (type) {
   1110        case HANDSHAKE_TYPE.CLIENT_HELLO:
   1111          msg = messages_ClientHello._read(buf);
   1112          break;
   1113        case HANDSHAKE_TYPE.SERVER_HELLO:
   1114          msg = messages_ServerHello._read(buf);
   1115          break;
   1116        case HANDSHAKE_TYPE.NEW_SESSION_TICKET:
   1117          msg = messages_NewSessionTicket._read(buf);
   1118          break;
   1119        case HANDSHAKE_TYPE.ENCRYPTED_EXTENSIONS:
   1120          msg = EncryptedExtensions._read(buf);
   1121          break;
   1122        case HANDSHAKE_TYPE.FINISHED:
   1123          msg = messages_Finished._read(buf);
   1124          break;
   1125      }
   1126      if (buf.hasMoreBytes()) {
   1127        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   1128      }
   1129    });
   1130    if (msg === null) {
   1131      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1132    }
   1133    return msg;
   1134  }
   1135 
   1136  write(buf) {
   1137    buf.writeUint8(this.TYPE_TAG);
   1138    buf.writeVector24(buf => {
   1139      this._write(buf);
   1140    });
   1141  }
   1142 
   1143  static _read(buf) {
   1144    throw new Error('not implemented');
   1145  }
   1146 
   1147  _write(buf) {
   1148    throw new Error('not implemented');
   1149  }
   1150 
   1151  // Some little helpers for reading a list of extensions,
   1152  // which is uniformly represented as:
   1153  //
   1154  //   Extension extensions<8..2^16-1>;
   1155  //
   1156  // Recognized extensions are returned as a Map from extension type
   1157  // to extension data object, with a special `lastSeenExtension`
   1158  // property to make it easy to check which one came last.
   1159 
   1160  static _readExtensions(messageType, buf) {
   1161    const extensions = new Map();
   1162    buf.readVector16(buf => {
   1163      const ext = extensions_Extension.read(messageType, buf);
   1164      if (extensions.has(ext.TYPE_TAG)) {
   1165        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   1166      }
   1167      extensions.set(ext.TYPE_TAG, ext);
   1168      extensions.lastSeenExtension = ext.TYPE_TAG;
   1169    });
   1170    return extensions;
   1171  }
   1172 
   1173  _writeExtensions(buf, extensions) {
   1174    buf.writeVector16(buf => {
   1175      extensions.forEach(ext => {
   1176        ext.write(this.TYPE_TAG, buf);
   1177      });
   1178    });
   1179  }
   1180 }
   1181 
   1182 
   1183 // The ClientHello message:
   1184 //
   1185 // struct {
   1186 //   ProtocolVersion legacy_version = 0x0303;
   1187 //   Random random;
   1188 //   opaque legacy_session_id<0..32>;
   1189 //   CipherSuite cipher_suites<2..2^16-2>;
   1190 //   opaque legacy_compression_methods<1..2^8-1>;
   1191 //   Extension extensions<8..2^16-1>;
   1192 // } ClientHello;
   1193 
   1194 class messages_ClientHello extends messages_HandshakeMessage {
   1195 
   1196  constructor(random, sessionId, extensions) {
   1197    super();
   1198    this.random = random;
   1199    this.sessionId = sessionId;
   1200    this.extensions = extensions;
   1201  }
   1202 
   1203  get TYPE_TAG() {
   1204    return HANDSHAKE_TYPE.CLIENT_HELLO;
   1205  }
   1206 
   1207  static _read(buf) {
   1208    // The legacy_version field may indicate an earlier version of TLS
   1209    // for backwards compatibility, but must not predate TLS 1.0!
   1210    if (buf.readUint16() < VERSION_TLS_1_0) {
   1211      throw new TLSError(ALERT_DESCRIPTION.PROTOCOL_VERSION);
   1212    }
   1213    // The random bytes provided by the peer.
   1214    const random = buf.readBytes(32);
   1215    // Read legacy_session_id, so the server can echo it.
   1216    const sessionId = buf.readVectorBytes8();
   1217    // We only support a single ciphersuite, but the peer may offer several.
   1218    // Scan the list to confirm that the one we want is present.
   1219    let found = false;
   1220    buf.readVector16(buf => {
   1221      const cipherSuite = buf.readUint16();
   1222      if (cipherSuite === TLS_AES_128_GCM_SHA256) {
   1223        found = true;
   1224      }
   1225    });
   1226    if (! found) {
   1227      throw new TLSError(ALERT_DESCRIPTION.HANDSHAKE_FAILURE);
   1228    }
   1229    // legacy_compression_methods must be a single zero byte for TLS1.3 ClientHellos.
   1230    // It can be non-zero in previous versions of TLS, but we're not going to
   1231    // make a successful handshake with such versions, so better to just bail out now.
   1232    const legacyCompressionMethods = buf.readVectorBytes8();
   1233    if (legacyCompressionMethods.byteLength !== 1) {
   1234      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1235    }
   1236    if (legacyCompressionMethods[0] !== 0x00) {
   1237      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1238    }
   1239    // Read and check the extensions.
   1240    const extensions = this._readExtensions(HANDSHAKE_TYPE.CLIENT_HELLO, buf);
   1241    if (! extensions.has(EXTENSION_TYPE.SUPPORTED_VERSIONS)) {
   1242      throw new TLSError(ALERT_DESCRIPTION.MISSING_EXTENSION);
   1243    }
   1244    if (extensions.get(EXTENSION_TYPE.SUPPORTED_VERSIONS).versions.indexOf(VERSION_TLS_1_3) === -1) {
   1245      throw new TLSError(ALERT_DESCRIPTION.PROTOCOL_VERSION);
   1246    }
   1247    // Was the PreSharedKey extension the last one?
   1248    if (extensions.has(EXTENSION_TYPE.PRE_SHARED_KEY)) {
   1249      if (extensions.lastSeenExtension !== EXTENSION_TYPE.PRE_SHARED_KEY) {
   1250        throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1251      }
   1252    }
   1253    return new this(random, sessionId, extensions);
   1254  }
   1255 
   1256  _write(buf) {
   1257    buf.writeUint16(VERSION_TLS_1_2);
   1258    buf.writeBytes(this.random);
   1259    buf.writeVectorBytes8(this.sessionId);
   1260    // Our single supported ciphersuite
   1261    buf.writeVector16(buf => {
   1262      buf.writeUint16(TLS_AES_128_GCM_SHA256);
   1263    });
   1264    // A single zero byte for legacy_compression_methods
   1265    buf.writeVectorBytes8(new Uint8Array(1));
   1266    this._writeExtensions(buf, this.extensions);
   1267  }
   1268 }
   1269 
   1270 
   1271 // The ServerHello message:
   1272 //
   1273 //  struct {
   1274 //      ProtocolVersion legacy_version = 0x0303;    /* TLS v1.2 */
   1275 //      Random random;
   1276 //      opaque legacy_session_id_echo<0..32>;
   1277 //      CipherSuite cipher_suite;
   1278 //      uint8 legacy_compression_method = 0;
   1279 //      Extension extensions < 6..2 ^ 16 - 1 >;
   1280 //  } ServerHello;
   1281 
   1282 class messages_ServerHello extends messages_HandshakeMessage {
   1283 
   1284  constructor(random, sessionId, extensions) {
   1285    super();
   1286    this.random = random;
   1287    this.sessionId = sessionId;
   1288    this.extensions = extensions;
   1289  }
   1290 
   1291  get TYPE_TAG() {
   1292    return HANDSHAKE_TYPE.SERVER_HELLO;
   1293  }
   1294 
   1295  static _read(buf) {
   1296    // Fixed value for legacy_version.
   1297    if (buf.readUint16() !== VERSION_TLS_1_2) {
   1298      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1299    }
   1300    // Random bytes from the server.
   1301    const random = buf.readBytes(32);
   1302    // It should have echoed our vector for legacy_session_id.
   1303    const sessionId = buf.readVectorBytes8();
   1304    // It should have selected our single offered ciphersuite.
   1305    if (buf.readUint16() !== TLS_AES_128_GCM_SHA256) {
   1306      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1307    }
   1308    // legacy_compression_method must be zero.
   1309    if (buf.readUint8() !== 0) {
   1310      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1311    }
   1312    const extensions = this._readExtensions(HANDSHAKE_TYPE.SERVER_HELLO, buf);
   1313    if (! extensions.has(EXTENSION_TYPE.SUPPORTED_VERSIONS)) {
   1314      throw new TLSError(ALERT_DESCRIPTION.MISSING_EXTENSION);
   1315    }
   1316    if (extensions.get(EXTENSION_TYPE.SUPPORTED_VERSIONS).selectedVersion !== VERSION_TLS_1_3) {
   1317      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1318    }
   1319    return new this(random, sessionId, extensions);
   1320  }
   1321 
   1322  _write(buf) {
   1323    buf.writeUint16(VERSION_TLS_1_2);
   1324    buf.writeBytes(this.random);
   1325    buf.writeVectorBytes8(this.sessionId);
   1326    // Our single supported ciphersuite
   1327    buf.writeUint16(TLS_AES_128_GCM_SHA256);
   1328    // A single zero byte for legacy_compression_method
   1329    buf.writeUint8(0);
   1330    this._writeExtensions(buf, this.extensions);
   1331  }
   1332 }
   1333 
   1334 
   1335 // The EncryptedExtensions message:
   1336 //
   1337 //  struct {
   1338 //    Extension extensions < 0..2 ^ 16 - 1 >;
   1339 //  } EncryptedExtensions;
   1340 //
   1341 // We don't actually send any EncryptedExtensions,
   1342 // but still have to send an empty message.
   1343 
   1344 class EncryptedExtensions extends messages_HandshakeMessage {
   1345  constructor(extensions) {
   1346    super();
   1347    this.extensions = extensions;
   1348  }
   1349 
   1350  get TYPE_TAG() {
   1351    return HANDSHAKE_TYPE.ENCRYPTED_EXTENSIONS;
   1352  }
   1353 
   1354  static _read(buf) {
   1355    const extensions = this._readExtensions(HANDSHAKE_TYPE.ENCRYPTED_EXTENSIONS, buf);
   1356    return new this(extensions);
   1357  }
   1358 
   1359  _write(buf) {
   1360    this._writeExtensions(buf, this.extensions);
   1361  }
   1362 }
   1363 
   1364 
   1365 // The Finished message:
   1366 //
   1367 // struct {
   1368 //   opaque verify_data[Hash.length];
   1369 // } Finished;
   1370 
   1371 class messages_Finished extends messages_HandshakeMessage {
   1372 
   1373  constructor(verifyData) {
   1374    super();
   1375    this.verifyData = verifyData;
   1376  }
   1377 
   1378  get TYPE_TAG() {
   1379    return HANDSHAKE_TYPE.FINISHED;
   1380  }
   1381 
   1382  static _read(buf) {
   1383    const verifyData = buf.readBytes(HASH_LENGTH);
   1384    return new this(verifyData);
   1385  }
   1386 
   1387  _write(buf) {
   1388    buf.writeBytes(this.verifyData);
   1389  }
   1390 }
   1391 
   1392 
   1393 // The NewSessionTicket message:
   1394 //
   1395 //   struct {
   1396 //    uint32 ticket_lifetime;
   1397 //    uint32 ticket_age_add;
   1398 //    opaque ticket_nonce < 0..255 >;
   1399 //    opaque ticket < 1..2 ^ 16 - 1 >;
   1400 //    Extension extensions < 0..2 ^ 16 - 2 >;
   1401 //  } NewSessionTicket;
   1402 //
   1403 // We don't actually make use of these, but we need to be able
   1404 // to accept them and do basic validation.
   1405 
   1406 class messages_NewSessionTicket extends messages_HandshakeMessage {
   1407  constructor(ticketLifetime, ticketAgeAdd, ticketNonce, ticket, extensions) {
   1408    super();
   1409    this.ticketLifetime = ticketLifetime;
   1410    this.ticketAgeAdd = ticketAgeAdd;
   1411    this.ticketNonce = ticketNonce;
   1412    this.ticket = ticket;
   1413    this.extensions = extensions;
   1414  }
   1415 
   1416  get TYPE_TAG() {
   1417    return HANDSHAKE_TYPE.NEW_SESSION_TICKET;
   1418  }
   1419 
   1420  static _read(buf) {
   1421    const ticketLifetime = buf.readUint32();
   1422    const ticketAgeAdd = buf.readUint32();
   1423    const ticketNonce = buf.readVectorBytes8();
   1424    const ticket = buf.readVectorBytes16();
   1425    if (ticket.byteLength < 1) {
   1426      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   1427    }
   1428    const extensions = this._readExtensions(HANDSHAKE_TYPE.NEW_SESSION_TICKET, buf);
   1429    return new this(ticketLifetime, ticketAgeAdd, ticketNonce, ticket, extensions);
   1430  }
   1431 
   1432  _write(buf) {
   1433    buf.writeUint32(this.ticketLifetime);
   1434    buf.writeUint32(this.ticketAgeAdd);
   1435    buf.writeVectorBytes8(this.ticketNonce);
   1436    buf.writeVectorBytes16(this.ticket);
   1437    this._writeExtensions(buf, this.extensions);
   1438  }
   1439 }
   1440 
   1441 // CONCATENATED MODULE: ./src/states.js
   1442 /* This Source Code Form is subject to the terms of the Mozilla Public
   1443 * License, v. 2.0. If a copy of the MPL was not distributed with this
   1444 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   1445 
   1446 
   1447 
   1448 
   1449 
   1450 
   1451 
   1452 
   1453 //
   1454 // State-machine for TLS Handshake Management.
   1455 //
   1456 // Internally, we manage the TLS connection by explicitly modelling the
   1457 // client and server state-machines from RFC8446.  You can think of
   1458 // these `State` objects as little plugins for the `Connection` class
   1459 // that provide different behaviours of `send` and `receive` depending
   1460 // on the state of the connection.
   1461 //
   1462 
   1463 class states_State {
   1464 
   1465  constructor(conn) {
   1466    this.conn = conn;
   1467  }
   1468 
   1469  async initialize() {
   1470    // By default, nothing to do when entering the state.
   1471  }
   1472 
   1473  async sendApplicationData(bytes) {
   1474    // By default, assume we're not ready to send yet and the caller
   1475    // should be blocking on the connection promise before reaching here.
   1476    throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1477  }
   1478 
   1479  async recvApplicationData(bytes) {
   1480    throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1481  }
   1482 
   1483  async recvHandshakeMessage(msg) {
   1484    throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1485  }
   1486 
   1487  async recvAlertMessage(alert) {
   1488    switch (alert.description) {
   1489      case ALERT_DESCRIPTION.CLOSE_NOTIFY:
   1490        this.conn._closeForRecv(alert);
   1491        throw alert;
   1492      default:
   1493        return await this.handleErrorAndRethrow(alert);
   1494    }
   1495  }
   1496 
   1497  async recvChangeCipherSpec(bytes) {
   1498    throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1499  }
   1500 
   1501  async handleErrorAndRethrow(err) {
   1502    let alert = err;
   1503    if (! (alert instanceof TLSAlert)) {
   1504      alert = new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1505    }
   1506    // Try to send error alert to the peer, but we may not
   1507    // be able to if the outgoing connection was already closed.
   1508    try {
   1509      await this.conn._sendAlertMessage(alert);
   1510    } catch (_) { }
   1511    await this.conn._transition(ERROR, err);
   1512    throw err;
   1513  }
   1514 
   1515  async close() {
   1516    const alert = new TLSCloseNotify();
   1517    await this.conn._sendAlertMessage(alert);
   1518    this.conn._closeForSend(alert);
   1519  }
   1520 
   1521 }
   1522 
   1523 // A special "guard" state to prevent us from using
   1524 // an improperly-initialized Connection.
   1525 
   1526 class UNINITIALIZED extends states_State {
   1527  async initialize() {
   1528    throw new Error('uninitialized state');
   1529  }
   1530  async sendApplicationData(bytes) {
   1531    throw new Error('uninitialized state');
   1532  }
   1533  async recvApplicationData(bytes) {
   1534    throw new Error('uninitialized state');
   1535  }
   1536  async recvHandshakeMessage(msg) {
   1537    throw new Error('uninitialized state');
   1538  }
   1539  async recvChangeCipherSpec(bytes) {
   1540    throw new Error('uninitialized state');
   1541  }
   1542  async handleErrorAndRethrow(err) {
   1543    throw err;
   1544  }
   1545  async close() {
   1546    throw new Error('uninitialized state');
   1547  }
   1548 }
   1549 
   1550 // A special "error" state for when something goes wrong.
   1551 // This state never transitions to another state, effectively
   1552 // terminating the connection.
   1553 
   1554 class ERROR extends states_State {
   1555  async initialize(err) {
   1556    this.error = err;
   1557    this.conn._setConnectionFailure(err);
   1558    // Unceremoniously shut down the record layer on error.
   1559    this.conn._recordlayer.setSendError(err);
   1560    this.conn._recordlayer.setRecvError(err);
   1561  }
   1562  async sendApplicationData(bytes) {
   1563    throw this.error;
   1564  }
   1565  async recvApplicationData(bytes) {
   1566    throw this.error;
   1567  }
   1568  async recvHandshakeMessage(msg) {
   1569    throw this.error;
   1570  }
   1571  async recvAlertMessage(err) {
   1572    throw this.error;
   1573  }
   1574  async recvChangeCipherSpec(bytes) {
   1575    throw this.error;
   1576  }
   1577  async handleErrorAndRethrow(err) {
   1578    throw err;
   1579  }
   1580  async close() {
   1581    throw this.error;
   1582  }
   1583 }
   1584 
   1585 // The "connected" state, for when the handshake is complete
   1586 // and we're ready to send application-level data.
   1587 // The logic for this is largely symmetric between client and server.
   1588 
   1589 class states_CONNECTED extends states_State {
   1590  async initialize() {
   1591    this.conn._setConnectionSuccess();
   1592  }
   1593  async sendApplicationData(bytes) {
   1594    await this.conn._sendApplicationData(bytes);
   1595  }
   1596  async recvApplicationData(bytes) {
   1597    return bytes;
   1598  }
   1599  async recvChangeCipherSpec(bytes) {
   1600    throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1601  }
   1602 }
   1603 
   1604 // A base class for states that occur in the middle of the handshake
   1605 // (that is, between ClientHello and Finished).  These states may receive
   1606 // CHANGE_CIPHER_SPEC records for b/w compat reasons, which must contain
   1607 // exactly a single 0x01 byte and must otherwise be ignored.
   1608 
   1609 class states_MidHandshakeState extends states_State {
   1610  async recvChangeCipherSpec(bytes) {
   1611    if (this.conn._hasSeenChangeCipherSpec) {
   1612      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1613    }
   1614    if (bytes.byteLength !== 1 || bytes[0] !== 1) {
   1615      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1616    }
   1617    this.conn._hasSeenChangeCipherSpec = true;
   1618  }
   1619 }
   1620 
   1621 // These states implement (part of) the client state-machine from
   1622 // https://tools.ietf.org/html/rfc8446#appendix-A.1
   1623 //
   1624 // Since we're only implementing a small subset of TLS1.3,
   1625 // we only need a small subset of the handshake.  It basically goes:
   1626 //
   1627 //   * send ClientHello
   1628 //   * receive ServerHello
   1629 //   * receive EncryptedExtensions
   1630 //   * receive server Finished
   1631 //   * send client Finished
   1632 //
   1633 // We include some unused states for completeness, so that it's easier
   1634 // to check the implementation against the diagrams in the RFC.
   1635 
   1636 class states_CLIENT_START extends states_State {
   1637  async initialize() {
   1638    const keyschedule = this.conn._keyschedule;
   1639    await keyschedule.addPSK(this.conn.psk);
   1640    // Construct a ClientHello message with our single PSK.
   1641    // We can't know the PSK binder value yet, so we initially write zeros.
   1642    const clientHello = new messages_ClientHello(
   1643      // Client random salt.
   1644      await getRandomBytes(32),
   1645      // Random legacy_session_id; we *could* send an empty string here,
   1646      // but sending a random one makes it easier to be compatible with
   1647      // the data emitted by tlslite-ng for test-case generation.
   1648      await getRandomBytes(32),
   1649      [
   1650        new extensions_SupportedVersionsExtension([VERSION_TLS_1_3]),
   1651        new extensions_PskKeyExchangeModesExtension([PSK_MODE_KE]),
   1652        new extensions_PreSharedKeyExtension([this.conn.pskId], [zeros(HASH_LENGTH)]),
   1653      ],
   1654    );
   1655    const buf = new utils_BufferWriter();
   1656    clientHello.write(buf);
   1657    // Now that we know what the ClientHello looks like,
   1658    // go back and calculate the appropriate PSK binder value.
   1659    // We only support a single PSK, so the length of the binders field is the
   1660    // length of the hash plus one for rendering it as a variable-length byte array,
   1661    // plus two for rendering the variable-length list of PSK binders.
   1662    const PSK_BINDERS_SIZE = HASH_LENGTH + 1 + 2;
   1663    const truncatedTranscript = buf.slice(0, buf.tell() - PSK_BINDERS_SIZE);
   1664    const pskBinder = await keyschedule.calculateFinishedMAC(keyschedule.extBinderKey, truncatedTranscript);
   1665    buf.incr(-HASH_LENGTH);
   1666    buf.writeBytes(pskBinder);
   1667    await this.conn._sendHandshakeMessageBytes(buf.flush());
   1668    await this.conn._transition(states_CLIENT_WAIT_SH, clientHello.sessionId);
   1669  }
   1670 }
   1671 
   1672 class states_CLIENT_WAIT_SH extends states_State {
   1673  async initialize(sessionId) {
   1674    this._sessionId = sessionId;
   1675  }
   1676  async recvHandshakeMessage(msg) {
   1677    if (! (msg instanceof messages_ServerHello)) {
   1678      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1679    }
   1680    if (! bytesAreEqual(msg.sessionId, this._sessionId)) {
   1681      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1682    }
   1683    const pskExt = msg.extensions.get(EXTENSION_TYPE.PRE_SHARED_KEY);
   1684    if (! pskExt) {
   1685      throw new TLSError(ALERT_DESCRIPTION.MISSING_EXTENSION);
   1686    }
   1687    // We expect only the SUPPORTED_VERSIONS and PRE_SHARED_KEY extensions.
   1688    if (msg.extensions.size !== 2) {
   1689      throw new TLSError(ALERT_DESCRIPTION.UNSUPPORTED_EXTENSION);
   1690    }
   1691    if (pskExt.selectedIdentity !== 0) {
   1692      throw new TLSError(ALERT_DESCRIPTION.ILLEGAL_PARAMETER);
   1693    }
   1694    await this.conn._keyschedule.addECDHE(null);
   1695    await this.conn._setSendKey(this.conn._keyschedule.clientHandshakeTrafficSecret);
   1696    await this.conn._setRecvKey(this.conn._keyschedule.serverHandshakeTrafficSecret);
   1697    await this.conn._transition(states_CLIENT_WAIT_EE);
   1698  }
   1699 }
   1700 
   1701 class states_CLIENT_WAIT_EE extends states_MidHandshakeState {
   1702  async recvHandshakeMessage(msg) {
   1703    // We don't make use of any encrypted extensions, but we still
   1704    // have to wait for the server to send the (empty) list of them.
   1705    if (! (msg instanceof EncryptedExtensions)) {
   1706      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1707    }
   1708    // We do not support any EncryptedExtensions.
   1709    if (msg.extensions.size !== 0) {
   1710      throw new TLSError(ALERT_DESCRIPTION.UNSUPPORTED_EXTENSION);
   1711    }
   1712    const keyschedule = this.conn._keyschedule;
   1713    const serverFinishedTranscript = keyschedule.getTranscript();
   1714    await this.conn._transition(states_CLIENT_WAIT_FINISHED, serverFinishedTranscript);
   1715  }
   1716 }
   1717 
   1718 class states_CLIENT_WAIT_FINISHED extends states_State {
   1719  async initialize(serverFinishedTranscript) {
   1720    this._serverFinishedTranscript = serverFinishedTranscript;
   1721  }
   1722  async recvHandshakeMessage(msg) {
   1723    if (! (msg instanceof messages_Finished)) {
   1724      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1725    }
   1726    // Verify server Finished MAC.
   1727    const keyschedule = this.conn._keyschedule;
   1728    await keyschedule.verifyFinishedMAC(keyschedule.serverHandshakeTrafficSecret, msg.verifyData, this._serverFinishedTranscript);
   1729    // Send our own Finished message in return.
   1730    // This must be encrypted with the handshake traffic key,
   1731    // but must not appear in the transcript used to calculate the application keys.
   1732    const clientFinishedMAC = await keyschedule.calculateFinishedMAC(keyschedule.clientHandshakeTrafficSecret);
   1733    await keyschedule.finalize();
   1734    await this.conn._sendHandshakeMessage(new messages_Finished(clientFinishedMAC));
   1735    await this.conn._setSendKey(keyschedule.clientApplicationTrafficSecret);
   1736    await this.conn._setRecvKey(keyschedule.serverApplicationTrafficSecret);
   1737    await this.conn._transition(states_CLIENT_CONNECTED);
   1738  }
   1739 }
   1740 
   1741 class states_CLIENT_CONNECTED extends states_CONNECTED {
   1742  async recvHandshakeMessage(msg) {
   1743    // A connected client must be prepared to accept NewSessionTicket
   1744    // messages.  We never use them, but other server implementations
   1745    // might send them.
   1746    if (! (msg instanceof messages_NewSessionTicket)) {
   1747      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1748    }
   1749  }
   1750 }
   1751 
   1752 // These states implement (part of) the server state-machine from
   1753 // https://tools.ietf.org/html/rfc8446#appendix-A.2
   1754 //
   1755 // Since we're only implementing a small subset of TLS1.3,
   1756 // we only need a small subset of the handshake.  It basically goes:
   1757 //
   1758 //   * receive ClientHello
   1759 //   * send ServerHello
   1760 //   * send empty EncryptedExtensions
   1761 //   * send server Finished
   1762 //   * receive client Finished
   1763 //
   1764 // We include some unused states for completeness, so that it's easier
   1765 // to check the implementation against the diagrams in the RFC.
   1766 
   1767 class states_SERVER_START extends states_State {
   1768  async recvHandshakeMessage(msg) {
   1769    if (! (msg instanceof messages_ClientHello)) {
   1770      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1771    }
   1772    // In the spec, this is where we select connection parameters, and maybe
   1773    // tell the client to try again if we can't find a compatible set.
   1774    // Since we only support a fixed cipherset, the only thing to "negotiate"
   1775    // is whether they provided an acceptable PSK.
   1776    const pskExt = msg.extensions.get(EXTENSION_TYPE.PRE_SHARED_KEY);
   1777    const pskModesExt = msg.extensions.get(EXTENSION_TYPE.PSK_KEY_EXCHANGE_MODES);
   1778    if (! pskExt || ! pskModesExt) {
   1779      throw new TLSError(ALERT_DESCRIPTION.MISSING_EXTENSION);
   1780    }
   1781    if (pskModesExt.modes.indexOf(PSK_MODE_KE) === -1) {
   1782      throw new TLSError(ALERT_DESCRIPTION.HANDSHAKE_FAILURE);
   1783    }
   1784    const pskIndex = pskExt.identities.findIndex(pskId => bytesAreEqual(pskId, this.conn.pskId));
   1785    if (pskIndex === -1) {
   1786      throw new TLSError(ALERT_DESCRIPTION.UNKNOWN_PSK_IDENTITY);
   1787    }
   1788    await this.conn._keyschedule.addPSK(this.conn.psk);
   1789    // Validate the PSK binder.
   1790    const keyschedule = this.conn._keyschedule;
   1791    const transcript = keyschedule.getTranscript();
   1792    // Calculate size occupied by the PSK binders.
   1793    let pskBindersSize = 2; // Vector16 representation overhead.
   1794    for (const binder of pskExt.binders) {
   1795      pskBindersSize += binder.byteLength + 1; // Vector8 representation overhead.
   1796    }
   1797    await keyschedule.verifyFinishedMAC(keyschedule.extBinderKey, pskExt.binders[pskIndex], transcript.slice(0, -pskBindersSize));
   1798    await this.conn._transition(states_SERVER_NEGOTIATED, msg.sessionId, pskIndex);
   1799  }
   1800 }
   1801 
   1802 class states_SERVER_NEGOTIATED extends states_MidHandshakeState {
   1803  async initialize(sessionId, pskIndex) {
   1804    await this.conn._sendHandshakeMessage(new messages_ServerHello(
   1805      // Server random
   1806      await getRandomBytes(32),
   1807      sessionId,
   1808      [
   1809        new extensions_SupportedVersionsExtension(null, VERSION_TLS_1_3),
   1810        new extensions_PreSharedKeyExtension(null, null, pskIndex),
   1811      ]
   1812    ));
   1813    // If the client sent a non-empty sessionId, the server *must* send a change-cipher-spec for b/w compat.
   1814    if (sessionId.byteLength > 0) {
   1815      await this.conn._sendChangeCipherSpec();
   1816    }
   1817    // We can now transition to the encrypted part of the handshake.
   1818    const keyschedule = this.conn._keyschedule;
   1819    await keyschedule.addECDHE(null);
   1820    await this.conn._setSendKey(keyschedule.serverHandshakeTrafficSecret);
   1821    await this.conn._setRecvKey(keyschedule.clientHandshakeTrafficSecret);
   1822    // Send an empty EncryptedExtensions message.
   1823    await this.conn._sendHandshakeMessage(new EncryptedExtensions([]));
   1824    // Send the Finished message.
   1825    const serverFinishedMAC = await keyschedule.calculateFinishedMAC(keyschedule.serverHandshakeTrafficSecret);
   1826    await this.conn._sendHandshakeMessage(new messages_Finished(serverFinishedMAC));
   1827    // We can now *send* using the application traffic key,
   1828    // but have to wait to receive the client Finished before receiving under that key.
   1829    // We need to remember the handshake state from before the client Finished
   1830    // in order to successfully verify the client Finished.
   1831    const clientFinishedTranscript = await keyschedule.getTranscript();
   1832    const clientHandshakeTrafficSecret = keyschedule.clientHandshakeTrafficSecret;
   1833    await keyschedule.finalize();
   1834    await this.conn._setSendKey(keyschedule.serverApplicationTrafficSecret);
   1835    await this.conn._transition(states_SERVER_WAIT_FINISHED, clientHandshakeTrafficSecret, clientFinishedTranscript);
   1836  }
   1837 }
   1838 
   1839 class states_SERVER_WAIT_FINISHED extends states_MidHandshakeState {
   1840  async initialize(clientHandshakeTrafficSecret, clientFinishedTranscript) {
   1841    this._clientHandshakeTrafficSecret = clientHandshakeTrafficSecret;
   1842    this._clientFinishedTranscript = clientFinishedTranscript;
   1843  }
   1844  async recvHandshakeMessage(msg) {
   1845    if (! (msg instanceof messages_Finished)) {
   1846      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   1847    }
   1848    const keyschedule = this.conn._keyschedule;
   1849    await keyschedule.verifyFinishedMAC(this._clientHandshakeTrafficSecret, msg.verifyData, this._clientFinishedTranscript);
   1850    this._clientHandshakeTrafficSecret = this._clientFinishedTranscript = null;
   1851    await this.conn._setRecvKey(keyschedule.clientApplicationTrafficSecret);
   1852    await this.conn._transition(states_CONNECTED);
   1853  }
   1854 }
   1855 
   1856 // CONCATENATED MODULE: ./src/keyschedule.js
   1857 /* This Source Code Form is subject to the terms of the Mozilla Public
   1858 * License, v. 2.0. If a copy of the MPL was not distributed with this
   1859 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   1860 
   1861 // TLS1.3 Key Schedule.
   1862 //
   1863 // In this file we implement the "key schedule" from
   1864 // https://tools.ietf.org/html/rfc8446#section-7.1, which
   1865 // defines how to calculate various keys as the handshake
   1866 // state progresses.
   1867 
   1868 
   1869 
   1870 
   1871 
   1872 
   1873 
   1874 // The `KeySchedule` class progresses through three stages corresponding
   1875 // to the three phases of the TLS1.3 key schedule:
   1876 //
   1877 //   UNINITIALIZED
   1878 //       |
   1879 //       | addPSK()
   1880 //       v
   1881 //   EARLY_SECRET
   1882 //       |
   1883 //       | addECDHE()
   1884 //       v
   1885 //   HANDSHAKE_SECRET
   1886 //       |
   1887 //       | finalize()
   1888 //       v
   1889 //   MASTER_SECRET
   1890 //
   1891 // It will error out if the calling code attempts to add key material
   1892 // in the wrong order.
   1893 
   1894 const STAGE_UNINITIALIZED = 0;
   1895 const STAGE_EARLY_SECRET = 1;
   1896 const STAGE_HANDSHAKE_SECRET = 2;
   1897 const STAGE_MASTER_SECRET = 3;
   1898 
   1899 class keyschedule_KeySchedule {
   1900  constructor() {
   1901    this.stage = STAGE_UNINITIALIZED;
   1902    // WebCrypto doesn't support a rolling hash construct, so we have to
   1903    // keep the entire message transcript in memory.
   1904    this.transcript = new utils_BufferWriter();
   1905    // This tracks the main secret from with other keys are derived at each stage.
   1906    this.secret = null;
   1907    // And these are all the various keys we'll derive as the handshake progresses.
   1908    this.extBinderKey = null;
   1909    this.clientHandshakeTrafficSecret = null;
   1910    this.serverHandshakeTrafficSecret = null;
   1911    this.clientApplicationTrafficSecret = null;
   1912    this.serverApplicationTrafficSecret = null;
   1913  }
   1914 
   1915  async addPSK(psk) {
   1916    // Use the selected PSK (if any) to calculate the "early secret".
   1917    if (psk === null) {
   1918      psk = zeros(HASH_LENGTH);
   1919    }
   1920    if (this.stage !== STAGE_UNINITIALIZED) {
   1921      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1922    }
   1923    this.stage = STAGE_EARLY_SECRET;
   1924    this.secret = await hkdfExtract(zeros(HASH_LENGTH), psk);
   1925    this.extBinderKey = await this.deriveSecret('ext binder', EMPTY);
   1926    this.secret = await this.deriveSecret('derived', EMPTY);
   1927  }
   1928 
   1929  async addECDHE(ecdhe) {
   1930    // Mix in the ECDHE output (if any) to calculate the "handshake secret".
   1931    if (ecdhe === null) {
   1932      ecdhe = zeros(HASH_LENGTH);
   1933    }
   1934    if (this.stage !== STAGE_EARLY_SECRET) {
   1935      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1936    }
   1937    this.stage = STAGE_HANDSHAKE_SECRET;
   1938    this.extBinderKey = null;
   1939    this.secret = await hkdfExtract(this.secret, ecdhe);
   1940    this.clientHandshakeTrafficSecret = await this.deriveSecret('c hs traffic');
   1941    this.serverHandshakeTrafficSecret = await this.deriveSecret('s hs traffic');
   1942    this.secret = await this.deriveSecret('derived', EMPTY);
   1943  }
   1944 
   1945  async finalize() {
   1946    if (this.stage !== STAGE_HANDSHAKE_SECRET) {
   1947      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   1948    }
   1949    this.stage = STAGE_MASTER_SECRET;
   1950    this.clientHandshakeTrafficSecret = null;
   1951    this.serverHandshakeTrafficSecret = null;
   1952    this.secret = await hkdfExtract(this.secret, zeros(HASH_LENGTH));
   1953    this.clientApplicationTrafficSecret = await this.deriveSecret('c ap traffic');
   1954    this.serverApplicationTrafficSecret = await this.deriveSecret('s ap traffic');
   1955    this.secret = null;
   1956  }
   1957 
   1958  addToTranscript(bytes) {
   1959    this.transcript.writeBytes(bytes);
   1960  }
   1961 
   1962  getTranscript() {
   1963    return this.transcript.slice();
   1964  }
   1965 
   1966  async deriveSecret(label, transcript = undefined) {
   1967    transcript = transcript || this.getTranscript();
   1968    return await hkdfExpandLabel(this.secret, label, await hash(transcript), HASH_LENGTH);
   1969  }
   1970 
   1971  async calculateFinishedMAC(baseKey, transcript = undefined) {
   1972    transcript = transcript || this.getTranscript();
   1973    const finishedKey = await hkdfExpandLabel(baseKey, 'finished', EMPTY, HASH_LENGTH);
   1974    return await hmac(finishedKey, await hash(transcript));
   1975  }
   1976 
   1977  async verifyFinishedMAC(baseKey, mac, transcript = undefined) {
   1978    transcript = transcript || this.getTranscript();
   1979    const finishedKey = await hkdfExpandLabel(baseKey, 'finished', EMPTY, HASH_LENGTH);
   1980    await verifyHmac(finishedKey, mac, await hash(transcript));
   1981  }
   1982 }
   1983 
   1984 // CONCATENATED MODULE: ./src/recordlayer.js
   1985 /* This Source Code Form is subject to the terms of the Mozilla Public
   1986 * License, v. 2.0. If a copy of the MPL was not distributed with this
   1987 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   1988 
   1989 //
   1990 // This file implements the "record layer" for TLS1.3, as defined in
   1991 // https://tools.ietf.org/html/rfc8446#section-5.
   1992 //
   1993 // The record layer is responsible for encrypting/decrypting bytes to be
   1994 // sent over the wire, including stateful management of sequence numbers
   1995 // for the incoming and outgoing stream.
   1996 //
   1997 // The main interface is the RecordLayer class, which takes a callback function
   1998 // sending data and can be used like so:
   1999 //
   2000 //    rl = new RecordLayer(async function send_encrypted_data(data) {
   2001 //      // application-specific sending logic here.
   2002 //    });
   2003 //
   2004 //    // Records are sent and received in plaintext by default,
   2005 //    // until you specify the key to use.
   2006 //    await rl.setSendKey(key)
   2007 //
   2008 //    // Send some data by specifying the record type and the bytes.
   2009 //    // Where allowed by the record type, it will be buffered until
   2010 //    // explicitly flushed, and then sent by calling the callback.
   2011 //    await rl.send(RECORD_TYPE.HANDSHAKE, <bytes for a handshake message>)
   2012 //    await rl.send(RECORD_TYPE.HANDSHAKE, <bytes for another handshake message>)
   2013 //    await rl.flush()
   2014 //
   2015 //    // Separate keys are used for sending and receiving.
   2016 //    rl.setRecvKey(key);
   2017 //
   2018 //    // When data is received, push it into the RecordLayer
   2019 //    // and pass a callback that will be called with a [type, bytes]
   2020 //    // pair for each message parsed from the data.
   2021 //    rl.recv(dataReceivedFromPeer, async (type, bytes) => {
   2022 //      switch (type) {
   2023 //        case RECORD_TYPE.APPLICATION_DATA:
   2024 //          // do something with application data
   2025 //        case RECORD_TYPE.HANDSHAKE:
   2026 //          // do something with a handshake message
   2027 //        default:
   2028 //          // etc...
   2029 //      }
   2030 //    });
   2031 //
   2032 
   2033 
   2034 
   2035 
   2036 
   2037 
   2038 
   2039 /* eslint-disable sorting/sort-object-props */
   2040 const RECORD_TYPE = {
   2041  CHANGE_CIPHER_SPEC: 20,
   2042  ALERT: 21,
   2043  HANDSHAKE: 22,
   2044  APPLICATION_DATA: 23,
   2045 };
   2046 /* eslint-enable sorting/sort-object-props */
   2047 
   2048 // Encrypting at most 2^24 records will force us to stay
   2049 // below data limits on AES-GCM encryption key use, and also
   2050 // means we can accurately represent the sequence number as
   2051 // a javascript double.
   2052 const MAX_SEQUENCE_NUMBER = Math.pow(2, 24);
   2053 const MAX_RECORD_SIZE = Math.pow(2, 14);
   2054 const MAX_ENCRYPTED_RECORD_SIZE = MAX_RECORD_SIZE + 256;
   2055 const RECORD_HEADER_SIZE = 5;
   2056 
   2057 // These are some helper classes to manage the encryption/decryption state
   2058 // for a particular key.
   2059 
   2060 class recordlayer_CipherState {
   2061  constructor(key, iv) {
   2062    this.key = key;
   2063    this.iv = iv;
   2064    this.seqnum = 0;
   2065  }
   2066 
   2067  static async create(baseKey, mode) {
   2068    // Derive key and iv per https://tools.ietf.org/html/rfc8446#section-7.3
   2069    const key = await prepareKey(await hkdfExpandLabel(baseKey, 'key', EMPTY, KEY_LENGTH), mode);
   2070    const iv = await hkdfExpandLabel(baseKey, 'iv', EMPTY, IV_LENGTH);
   2071    return new this(key, iv);
   2072  }
   2073 
   2074  nonce() {
   2075    // Ref https://tools.ietf.org/html/rfc8446#section-5.3:
   2076    // * left-pad the sequence number with zeros to IV_LENGTH
   2077    // * xor with the provided iv
   2078    // Our sequence numbers are always less than 2^24, so fit in a Uint32
   2079    // in the last 4 bytes of the nonce.
   2080    const nonce = this.iv.slice();
   2081    const dv = new DataView(nonce.buffer, nonce.byteLength - 4, 4);
   2082    dv.setUint32(0, dv.getUint32(0) ^ this.seqnum);
   2083    this.seqnum += 1;
   2084    if (this.seqnum > MAX_SEQUENCE_NUMBER) {
   2085      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   2086    }
   2087    return nonce;
   2088  }
   2089 }
   2090 
   2091 class recordlayer_EncryptionState extends recordlayer_CipherState {
   2092  static async create(key) {
   2093    return super.create(key, 'encrypt');
   2094  }
   2095 
   2096  async encrypt(plaintext, additionalData) {
   2097    return await encrypt(this.key, this.nonce(), plaintext, additionalData);
   2098  }
   2099 }
   2100 
   2101 class recordlayer_DecryptionState extends recordlayer_CipherState {
   2102  static async create(key) {
   2103    return super.create(key, 'decrypt');
   2104  }
   2105 
   2106  async decrypt(ciphertext, additionalData) {
   2107    return await decrypt(this.key, this.nonce(), ciphertext, additionalData);
   2108  }
   2109 }
   2110 
   2111 // The main RecordLayer class.
   2112 
   2113 class recordlayer_RecordLayer {
   2114  constructor(sendCallback) {
   2115    this.sendCallback = sendCallback;
   2116    this._sendEncryptState = null;
   2117    this._sendError = null;
   2118    this._recvDecryptState = null;
   2119    this._recvError = null;
   2120    this._pendingRecordType = 0;
   2121    this._pendingRecordBuf = null;
   2122  }
   2123 
   2124  async setSendKey(key) {
   2125    await this.flush();
   2126    this._sendEncryptState = await recordlayer_EncryptionState.create(key);
   2127  }
   2128 
   2129  async setRecvKey(key) {
   2130    this._recvDecryptState = await recordlayer_DecryptionState.create(key);
   2131  }
   2132 
   2133  async setSendError(err) {
   2134    this._sendError = err;
   2135  }
   2136 
   2137  async setRecvError(err) {
   2138    this._recvError = err;
   2139  }
   2140 
   2141  async send(type, data) {
   2142    if (this._sendError !== null) {
   2143      throw this._sendError;
   2144    }
   2145    // Forbid sending data that doesn't fit into a single record.
   2146    // We do not support fragmentation over multiple records.
   2147    if (data.byteLength > MAX_RECORD_SIZE) {
   2148      throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   2149    }
   2150    // Flush if we're switching to a different record type.
   2151    if (this._pendingRecordType && this._pendingRecordType !== type) {
   2152      await this.flush();
   2153    }
   2154    // Flush if we would overflow the max size of a record.
   2155    if (this._pendingRecordBuf !== null) {
   2156      if (this._pendingRecordBuf.tell() + data.byteLength > MAX_RECORD_SIZE) {
   2157        await this.flush();
   2158      }
   2159    }
   2160    // Start a new pending record if necessary.
   2161    // We reserve space at the start of the buffer for the record header,
   2162    // which is conveniently always a fixed size.
   2163    if (this._pendingRecordBuf === null) {
   2164      this._pendingRecordType = type;
   2165      this._pendingRecordBuf = new utils_BufferWriter();
   2166      this._pendingRecordBuf.incr(RECORD_HEADER_SIZE);
   2167    }
   2168    this._pendingRecordBuf.writeBytes(data);
   2169  }
   2170 
   2171  async flush() {
   2172    // If there's nothing to flush, bail out early.
   2173    // Don't throw `_sendError` if we're not sending anything, because `flush()`
   2174    // can be called when we're trying to transition into an error state.
   2175    const buf = this._pendingRecordBuf;
   2176    let type = this._pendingRecordType;
   2177    if (! type) {
   2178      if (buf !== null) {
   2179        throw new TLSError(ALERT_DESCRIPTION.INTERNAL_ERROR);
   2180      }
   2181      return;
   2182    }
   2183    if (this._sendError !== null) {
   2184      throw this._sendError;
   2185    }
   2186    // If we're encrypting, turn the existing buffer contents into a `TLSInnerPlaintext` by
   2187    // appending the type. We don't do any zero-padding, although the spec allows it.
   2188    let inflation = 0, innerPlaintext = null;
   2189    if (this._sendEncryptState !== null) {
   2190      buf.writeUint8(type);
   2191      innerPlaintext = buf.slice(RECORD_HEADER_SIZE);
   2192      inflation = AEAD_SIZE_INFLATION;
   2193      type = RECORD_TYPE.APPLICATION_DATA;
   2194    }
   2195    // Write the common header for either `TLSPlaintext` or `TLSCiphertext` record.
   2196    const length = buf.tell() - RECORD_HEADER_SIZE + inflation;
   2197    buf.seek(0);
   2198    buf.writeUint8(type);
   2199    buf.writeUint16(VERSION_TLS_1_2);
   2200    buf.writeUint16(length);
   2201    // Followed by different payload depending on encryption status.
   2202    if (this._sendEncryptState !== null) {
   2203      const additionalData = buf.slice(0, RECORD_HEADER_SIZE);
   2204      const ciphertext = await this._sendEncryptState.encrypt(innerPlaintext, additionalData);
   2205      buf.writeBytes(ciphertext);
   2206    } else {
   2207      buf.incr(length);
   2208    }
   2209    this._pendingRecordBuf = null;
   2210    this._pendingRecordType = 0;
   2211    await this.sendCallback(buf.flush());
   2212  }
   2213 
   2214  async recv(data) {
   2215    if (this._recvError !== null) {
   2216      throw this._recvError;
   2217    }
   2218    // For simplicity, we assume that the given data contains exactly one record.
   2219    // Peers using this library will send one record at a time over the websocket
   2220    // connection, and we can assume that the server-side websocket bridge will split
   2221    // up any traffic into individual records if we ever start interoperating with
   2222    // peers using a different TLS implementation.
   2223    // Similarly, we assume that handshake messages will not be fragmented across
   2224    // multiple records. This should be trivially true for the PSK-only mode used
   2225    // by this library, but we may want to relax it in future for interoperability
   2226    // with e.g. large ClientHello messages that contain lots of different options.
   2227    const buf = new utils_BufferReader(data);
   2228    // The data to read is either a TLSPlaintext or TLSCiphertext struct,
   2229    // depending on whether record protection has been enabled yet:
   2230    //
   2231    //    struct {
   2232    //        ContentType type;
   2233    //        ProtocolVersion legacy_record_version;
   2234    //        uint16 length;
   2235    //        opaque fragment[TLSPlaintext.length];
   2236    //    } TLSPlaintext;
   2237    //
   2238    //    struct {
   2239    //        ContentType opaque_type = application_data; /* 23 */
   2240    //        ProtocolVersion legacy_record_version = 0x0303; /* TLS v1.2 */
   2241    //        uint16 length;
   2242    //        opaque encrypted_record[TLSCiphertext.length];
   2243    //    } TLSCiphertext;
   2244    //
   2245    let type = buf.readUint8();
   2246    // The spec says legacy_record_version "MUST be ignored for all purposes",
   2247    // but we know TLS1.3 implementations will only ever emit two possible values,
   2248    // so it seems useful to bail out early if we receive anything else.
   2249    const version = buf.readUint16();
   2250    if (version !== VERSION_TLS_1_2) {
   2251      // TLS1.0 is only acceptable on initial plaintext records.
   2252      if (this._recvDecryptState !== null || version !== VERSION_TLS_1_0) {
   2253        throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   2254      }
   2255    }
   2256    const length = buf.readUint16();
   2257    let plaintext;
   2258    if (this._recvDecryptState === null || type === RECORD_TYPE.CHANGE_CIPHER_SPEC) {
   2259      [type, plaintext] = await this._readPlaintextRecord(type, length, buf);
   2260    } else {
   2261      [type, plaintext] = await this._readEncryptedRecord(type, length, buf);
   2262    }
   2263    // Sanity-check that we received exactly one record.
   2264    if (buf.hasMoreBytes()) {
   2265      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   2266    }
   2267    return [type, plaintext];
   2268  }
   2269 
   2270  // Helper to read an unencrypted `TLSPlaintext` struct
   2271 
   2272  async _readPlaintextRecord(type, length, buf) {
   2273    if (length > MAX_RECORD_SIZE) {
   2274      throw new TLSError(ALERT_DESCRIPTION.RECORD_OVERFLOW);
   2275    }
   2276    return [type, buf.readBytes(length)];
   2277  }
   2278 
   2279  // Helper to read an encrypted `TLSCiphertext` struct,
   2280  // decrypting it into plaintext.
   2281 
   2282  async _readEncryptedRecord(type, length, buf) {
   2283    if (length > MAX_ENCRYPTED_RECORD_SIZE) {
   2284      throw new TLSError(ALERT_DESCRIPTION.RECORD_OVERFLOW);
   2285    }
   2286    // The outer type for encrypted records is always APPLICATION_DATA.
   2287    if (type !== RECORD_TYPE.APPLICATION_DATA) {
   2288      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   2289    }
   2290    // Decrypt and decode the contained `TLSInnerPlaintext` struct:
   2291    //
   2292    //    struct {
   2293    //        opaque content[TLSPlaintext.length];
   2294    //        ContentType type;
   2295    //        uint8 zeros[length_of_padding];
   2296    //    } TLSInnerPlaintext;
   2297    //
   2298    // The additional data for the decryption is the `TLSCiphertext` record
   2299    // header, which is a fixed size and immediately prior to current buffer position.
   2300    buf.incr(-RECORD_HEADER_SIZE);
   2301    const additionalData = buf.readBytes(RECORD_HEADER_SIZE);
   2302    const ciphertext = buf.readBytes(length);
   2303    const paddedPlaintext = await this._recvDecryptState.decrypt(ciphertext, additionalData);
   2304    // We have to scan backwards over the zero padding at the end of the struct
   2305    // in order to find the non-zero `type` byte.
   2306    let i;
   2307    for (i = paddedPlaintext.byteLength - 1; i >= 0; i--) {
   2308      if (paddedPlaintext[i] !== 0) {
   2309        break;
   2310      }
   2311    }
   2312    if (i < 0) {
   2313      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   2314    }
   2315    type = paddedPlaintext[i];
   2316    // `change_cipher_spec` records must always be plaintext.
   2317    if (type === RECORD_TYPE.CHANGE_CIPHER_SPEC) {
   2318      throw new TLSError(ALERT_DESCRIPTION.DECODE_ERROR);
   2319    }
   2320    return [type, paddedPlaintext.slice(0, i)];
   2321  }
   2322 }
   2323 
   2324 // CONCATENATED MODULE: ./src/tlsconnection.js
   2325 /* This Source Code Form is subject to the terms of the Mozilla Public
   2326 * License, v. 2.0. If a copy of the MPL was not distributed with this
   2327 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   2328 
   2329 // The top-level APIs offered by this module are `ClientConnection` and
   2330 // `ServerConnection` classes, which provide authenticated and encrypted
   2331 // communication via the "externally-provisioned PSK" mode of TLS1.3.
   2332 // They each take a callback to be used for sending data to the remote peer,
   2333 // and operate like this:
   2334 //
   2335 //    conn = await ClientConnection.create(psk, pskId, async function send_data_to_server(data) {
   2336 //      // application-specific sending logic here.
   2337 //    })
   2338 //
   2339 //    // Send data to the server by calling `send`,
   2340 //    // which will use the callback provided in the constructor.
   2341 //    // A single `send()` by the application may result in multiple
   2342 //    // invokations of the callback.
   2343 //
   2344 //    await conn.send('application-level data')
   2345 //
   2346 //    // When data is received from the server, push it into
   2347 //    // the connection and let it return any decrypted app-level data.
   2348 //    // There might not be any app-level data if it was a protocol control
   2349 //    //  message, and the receipt of the data might trigger additional calls
   2350 //    // to the send callback for protocol control purposes.
   2351 //
   2352 //    serverSocket.on('data', async encrypted_data => {
   2353 //      const plaintext = await conn.recv(data)
   2354 //      if (plaintext !== null) {
   2355 //        do_something_with_app_level_data(plaintext)
   2356 //      }
   2357 //    })
   2358 //
   2359 //    // It's good practice to explicitly close the connection
   2360 //    // when finished.  This will send a "closed" notification
   2361 //    // to the server.
   2362 //
   2363 //    await conn.close()
   2364 //
   2365 //    // When the peer sends a "closed" notification it will show up
   2366 //    // as a `TLSCloseNotify` exception from recv:
   2367 //
   2368 //    try {
   2369 //      data = await conn.recv(data);
   2370 //    } catch (err) {
   2371 //      if (! (err instanceof TLSCloseNotify) { throw err }
   2372 //      do_something_to_cleanly_close_data_connection();
   2373 //    }
   2374 //
   2375 // The `ServerConnection` API operates similarly; the distinction is mainly
   2376 // in which side is expected to send vs receieve during the protocol handshake.
   2377 
   2378 
   2379 
   2380 
   2381 
   2382 
   2383 
   2384 
   2385 
   2386 
   2387 class tlsconnection_Connection {
   2388  constructor(psk, pskId, sendCallback) {
   2389    this.psk = assertIsBytes(psk);
   2390    this.pskId = assertIsBytes(pskId);
   2391    this.connected = new Promise((resolve, reject) => {
   2392      this._onConnectionSuccess = resolve;
   2393      this._onConnectionFailure = reject;
   2394    });
   2395    this._state = new UNINITIALIZED(this);
   2396    this._handshakeRecvBuffer = null;
   2397    this._hasSeenChangeCipherSpec = false;
   2398    this._recordlayer = new recordlayer_RecordLayer(sendCallback);
   2399    this._keyschedule = new keyschedule_KeySchedule();
   2400    this._lastPromise = Promise.resolve();
   2401  }
   2402 
   2403  // Subclasses will override this with some async initialization logic.
   2404  static async create(psk, pskId, sendCallback) {
   2405    return new this(psk, pskId, sendCallback);
   2406  }
   2407 
   2408  // These are the three public API methods that consumers can use
   2409  // to send and receive data encrypted with TLS1.3.
   2410 
   2411  async send(data) {
   2412    assertIsBytes(data);
   2413    await this.connected;
   2414    await this._synchronized(async () => {
   2415      await this._state.sendApplicationData(data);
   2416    });
   2417  }
   2418 
   2419  async recv(data) {
   2420    assertIsBytes(data);
   2421    return await this._synchronized(async () => {
   2422      // Decrypt the data using the record layer.
   2423      // We expect to receive precisely one record at a time.
   2424      const [type, bytes] = await this._recordlayer.recv(data);
   2425      // Dispatch based on the type of the record.
   2426      switch (type) {
   2427        case RECORD_TYPE.CHANGE_CIPHER_SPEC:
   2428          await this._state.recvChangeCipherSpec(bytes);
   2429          return null;
   2430        case RECORD_TYPE.ALERT:
   2431          await this._state.recvAlertMessage(TLSAlert.fromBytes(bytes));
   2432          return null;
   2433        case RECORD_TYPE.APPLICATION_DATA:
   2434          return await this._state.recvApplicationData(bytes);
   2435        case RECORD_TYPE.HANDSHAKE:
   2436          // Multiple handshake messages may be coalesced into a single record.
   2437          // Store the in-progress record buffer on `this` so that we can guard
   2438          // against handshake messages that span a change in keys.
   2439          this._handshakeRecvBuffer = new utils_BufferReader(bytes);
   2440          if (! this._handshakeRecvBuffer.hasMoreBytes()) {
   2441            throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   2442          }
   2443          do {
   2444            // Each handshake messages has a type and length prefix, per
   2445            // https://tools.ietf.org/html/rfc8446#appendix-B.3
   2446            this._handshakeRecvBuffer.incr(1);
   2447            const mlength = this._handshakeRecvBuffer.readUint24();
   2448            this._handshakeRecvBuffer.incr(-4);
   2449            const messageBytes = this._handshakeRecvBuffer.readBytes(mlength + 4);
   2450            this._keyschedule.addToTranscript(messageBytes);
   2451            await this._state.recvHandshakeMessage(messages_HandshakeMessage.fromBytes(messageBytes));
   2452          } while (this._handshakeRecvBuffer.hasMoreBytes());
   2453          this._handshakeRecvBuffer = null;
   2454          return null;
   2455        default:
   2456          throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   2457      }
   2458    });
   2459  }
   2460 
   2461  async close() {
   2462    await this._synchronized(async () => {
   2463      await this._state.close();
   2464    });
   2465  }
   2466 
   2467  // Ensure that async functions execute one at a time,
   2468  // by waiting for the previous call to `_synchronized()` to complete
   2469  // before starting a new one.  This helps ensure that we complete
   2470  // one state-machine transition before starting to do the next.
   2471  // It's also a convenient place to catch and alert on errors.
   2472 
   2473  _synchronized(cb) {
   2474    const nextPromise = this._lastPromise.then(() => {
   2475      return cb();
   2476    }).catch(async err => {
   2477      if (err instanceof TLSCloseNotify) {
   2478        throw err;
   2479      }
   2480      await this._state.handleErrorAndRethrow(err);
   2481    });
   2482    // We don't want to hold on to the return value or error,
   2483    // just synchronize on the fact that it completed.
   2484    this._lastPromise = nextPromise.then(noop, noop);
   2485    return nextPromise;
   2486  }
   2487 
   2488  // This drives internal transition of the state-machine,
   2489  // ensuring that the new state is properly initialized.
   2490 
   2491  async _transition(State, ...args) {
   2492    this._state = new State(this);
   2493    await this._state.initialize(...args);
   2494    await this._recordlayer.flush();
   2495  }
   2496 
   2497  // These are helpers to allow the State to manipulate the recordlayer
   2498  // and send out various types of data.
   2499 
   2500  async _sendApplicationData(bytes) {
   2501    await this._recordlayer.send(RECORD_TYPE.APPLICATION_DATA, bytes);
   2502    await this._recordlayer.flush();
   2503  }
   2504 
   2505  async _sendHandshakeMessage(msg) {
   2506    await this._sendHandshakeMessageBytes(msg.toBytes());
   2507  }
   2508 
   2509  async _sendHandshakeMessageBytes(bytes) {
   2510    this._keyschedule.addToTranscript(bytes);
   2511    await this._recordlayer.send(RECORD_TYPE.HANDSHAKE, bytes);
   2512    // Don't flush after each handshake message, since we can probably
   2513    // coalesce multiple messages into a single record.
   2514  }
   2515 
   2516  async _sendAlertMessage(err) {
   2517    await this._recordlayer.send(RECORD_TYPE.ALERT, err.toBytes());
   2518    await this._recordlayer.flush();
   2519  }
   2520 
   2521  async _sendChangeCipherSpec() {
   2522    await this._recordlayer.send(RECORD_TYPE.CHANGE_CIPHER_SPEC, new Uint8Array([0x01]));
   2523    await this._recordlayer.flush();
   2524  }
   2525 
   2526  async _setSendKey(key) {
   2527    return await this._recordlayer.setSendKey(key);
   2528  }
   2529 
   2530  async _setRecvKey(key) {
   2531    // Handshake messages that change keys must be on a record boundary.
   2532    if (this._handshakeRecvBuffer && this._handshakeRecvBuffer.hasMoreBytes()) {
   2533      throw new TLSError(ALERT_DESCRIPTION.UNEXPECTED_MESSAGE);
   2534    }
   2535    return await this._recordlayer.setRecvKey(key);
   2536  }
   2537 
   2538  _setConnectionSuccess() {
   2539    if (this._onConnectionSuccess !== null) {
   2540      this._onConnectionSuccess();
   2541      this._onConnectionSuccess = null;
   2542      this._onConnectionFailure = null;
   2543    }
   2544  }
   2545 
   2546  _setConnectionFailure(err) {
   2547    if (this._onConnectionFailure !== null) {
   2548      this._onConnectionFailure(err);
   2549      this._onConnectionSuccess = null;
   2550      this._onConnectionFailure = null;
   2551    }
   2552  }
   2553 
   2554  _closeForSend(alert) {
   2555    this._recordlayer.setSendError(alert);
   2556  }
   2557 
   2558  _closeForRecv(alert) {
   2559    this._recordlayer.setRecvError(alert);
   2560  }
   2561 }
   2562 
   2563 class tlsconnection_ClientConnection extends tlsconnection_Connection {
   2564  static async create(psk, pskId, sendCallback) {
   2565    const instance = await super.create(psk, pskId, sendCallback);
   2566    await instance._transition(states_CLIENT_START);
   2567    return instance;
   2568  }
   2569 }
   2570 
   2571 class tlsconnection_ServerConnection extends tlsconnection_Connection {
   2572  static async create(psk, pskId, sendCallback) {
   2573    const instance = await super.create(psk, pskId, sendCallback);
   2574    await instance._transition(states_SERVER_START);
   2575    return instance;
   2576  }
   2577 }
   2578 
   2579 // CONCATENATED MODULE: ./node_modules/event-target-shim/dist/event-target-shim.mjs
   2580 /**
   2581 * @author Toru Nagashima <https://github.com/mysticatea>
   2582 * @copyright 2015 Toru Nagashima. All rights reserved.
   2583 * See LICENSE file in root directory for full license.
   2584 */
   2585 /**
   2586 * @typedef {object} PrivateData
   2587 * @property {EventTarget} eventTarget The event target.
   2588 * @property {{type:string}} event The original event object.
   2589 * @property {number} eventPhase The current event phase.
   2590 * @property {EventTarget|null} currentTarget The current event target.
   2591 * @property {boolean} canceled The flag to prevent default.
   2592 * @property {boolean} stopped The flag to stop propagation.
   2593 * @property {boolean} immediateStopped The flag to stop propagation immediately.
   2594 * @property {Function|null} passiveListener The listener if the current listener is passive. Otherwise this is null.
   2595 * @property {number} timeStamp The unix time.
   2596 * @private
   2597 */
   2598 
   2599 /**
   2600 * Private data for event wrappers.
   2601 * @type {WeakMap<Event, PrivateData>}
   2602 * @private
   2603 */
   2604 const privateData = new WeakMap();
   2605 
   2606 /**
   2607 * Cache for wrapper classes.
   2608 * @type {WeakMap<Object, Function>}
   2609 * @private
   2610 */
   2611 const wrappers = new WeakMap();
   2612 
   2613 /**
   2614 * Get private data.
   2615 * @param {Event} event The event object to get private data.
   2616 * @returns {PrivateData} The private data of the event.
   2617 * @private
   2618 */
   2619 function pd(event) {
   2620    const retv = privateData.get(event);
   2621    console.assert(
   2622        retv != null,
   2623        "'this' is expected an Event object, but got",
   2624        event
   2625    );
   2626    return retv
   2627 }
   2628 
   2629 /**
   2630 * https://dom.spec.whatwg.org/#set-the-canceled-flag
   2631 * @param data {PrivateData} private data.
   2632 */
   2633 function setCancelFlag(data) {
   2634    if (data.passiveListener != null) {
   2635        if (
   2636            typeof console !== "undefined" &&
   2637            typeof console.error === "function"
   2638        ) {
   2639            console.error(
   2640                "Unable to preventDefault inside passive event listener invocation.",
   2641                data.passiveListener
   2642            );
   2643        }
   2644        return
   2645    }
   2646    if (!data.event.cancelable) {
   2647        return
   2648    }
   2649 
   2650    data.canceled = true;
   2651    if (typeof data.event.preventDefault === "function") {
   2652        data.event.preventDefault();
   2653    }
   2654 }
   2655 
   2656 /**
   2657 * @see https://dom.spec.whatwg.org/#interface-event
   2658 * @private
   2659 */
   2660 /**
   2661 * The event wrapper.
   2662 * @constructor
   2663 * @param {EventTarget} eventTarget The event target of this dispatching.
   2664 * @param {Event|{type:string}} event The original event to wrap.
   2665 */
   2666 function Event(eventTarget, event) {
   2667    privateData.set(this, {
   2668        eventTarget,
   2669        event,
   2670        eventPhase: 2,
   2671        currentTarget: eventTarget,
   2672        canceled: false,
   2673        stopped: false,
   2674        immediateStopped: false,
   2675        passiveListener: null,
   2676        timeStamp: event.timeStamp || Date.now(),
   2677    });
   2678 
   2679    // https://heycam.github.io/webidl/#Unforgeable
   2680    Object.defineProperty(this, "isTrusted", { value: false, enumerable: true });
   2681 
   2682    // Define accessors
   2683    const keys = Object.keys(event);
   2684    for (let i = 0; i < keys.length; ++i) {
   2685        const key = keys[i];
   2686        if (!(key in this)) {
   2687            Object.defineProperty(this, key, defineRedirectDescriptor(key));
   2688        }
   2689    }
   2690 }
   2691 
   2692 // Should be enumerable, but class methods are not enumerable.
   2693 Event.prototype = {
   2694    /**
   2695     * The type of this event.
   2696     * @type {string}
   2697     */
   2698    get type() {
   2699        return pd(this).event.type
   2700    },
   2701 
   2702    /**
   2703     * The target of this event.
   2704     * @type {EventTarget}
   2705     */
   2706    get target() {
   2707        return pd(this).eventTarget
   2708    },
   2709 
   2710    /**
   2711     * The target of this event.
   2712     * @type {EventTarget}
   2713     */
   2714    get currentTarget() {
   2715        return pd(this).currentTarget
   2716    },
   2717 
   2718    /**
   2719     * @returns {EventTarget[]} The composed path of this event.
   2720     */
   2721    composedPath() {
   2722        const currentTarget = pd(this).currentTarget;
   2723        if (currentTarget == null) {
   2724            return []
   2725        }
   2726        return [currentTarget]
   2727    },
   2728 
   2729    /**
   2730     * Constant of NONE.
   2731     * @type {number}
   2732     */
   2733    get NONE() {
   2734        return 0
   2735    },
   2736 
   2737    /**
   2738     * Constant of CAPTURING_PHASE.
   2739     * @type {number}
   2740     */
   2741    get CAPTURING_PHASE() {
   2742        return 1
   2743    },
   2744 
   2745    /**
   2746     * Constant of AT_TARGET.
   2747     * @type {number}
   2748     */
   2749    get AT_TARGET() {
   2750        return 2
   2751    },
   2752 
   2753    /**
   2754     * Constant of BUBBLING_PHASE.
   2755     * @type {number}
   2756     */
   2757    get BUBBLING_PHASE() {
   2758        return 3
   2759    },
   2760 
   2761    /**
   2762     * The target of this event.
   2763     * @type {number}
   2764     */
   2765    get eventPhase() {
   2766        return pd(this).eventPhase
   2767    },
   2768 
   2769    /**
   2770     * Stop event bubbling.
   2771     * @returns {void}
   2772     */
   2773    stopPropagation() {
   2774        const data = pd(this);
   2775 
   2776        data.stopped = true;
   2777        if (typeof data.event.stopPropagation === "function") {
   2778            data.event.stopPropagation();
   2779        }
   2780    },
   2781 
   2782    /**
   2783     * Stop event bubbling.
   2784     * @returns {void}
   2785     */
   2786    stopImmediatePropagation() {
   2787        const data = pd(this);
   2788 
   2789        data.stopped = true;
   2790        data.immediateStopped = true;
   2791        if (typeof data.event.stopImmediatePropagation === "function") {
   2792            data.event.stopImmediatePropagation();
   2793        }
   2794    },
   2795 
   2796    /**
   2797     * The flag to be bubbling.
   2798     * @type {boolean}
   2799     */
   2800    get bubbles() {
   2801        return Boolean(pd(this).event.bubbles)
   2802    },
   2803 
   2804    /**
   2805     * The flag to be cancelable.
   2806     * @type {boolean}
   2807     */
   2808    get cancelable() {
   2809        return Boolean(pd(this).event.cancelable)
   2810    },
   2811 
   2812    /**
   2813     * Cancel this event.
   2814     * @returns {void}
   2815     */
   2816    preventDefault() {
   2817        setCancelFlag(pd(this));
   2818    },
   2819 
   2820    /**
   2821     * The flag to indicate cancellation state.
   2822     * @type {boolean}
   2823     */
   2824    get defaultPrevented() {
   2825        return pd(this).canceled
   2826    },
   2827 
   2828    /**
   2829     * The flag to be composed.
   2830     * @type {boolean}
   2831     */
   2832    get composed() {
   2833        return Boolean(pd(this).event.composed)
   2834    },
   2835 
   2836    /**
   2837     * The unix time of this event.
   2838     * @type {number}
   2839     */
   2840    get timeStamp() {
   2841        return pd(this).timeStamp
   2842    },
   2843 
   2844    /**
   2845     * The target of this event.
   2846     * @type {EventTarget}
   2847     * @deprecated
   2848     */
   2849    get srcElement() {
   2850        return pd(this).eventTarget
   2851    },
   2852 
   2853    /**
   2854     * The flag to stop event bubbling.
   2855     * @type {boolean}
   2856     * @deprecated
   2857     */
   2858    get cancelBubble() {
   2859        return pd(this).stopped
   2860    },
   2861    set cancelBubble(value) {
   2862        if (!value) {
   2863            return
   2864        }
   2865        const data = pd(this);
   2866 
   2867        data.stopped = true;
   2868        if (typeof data.event.cancelBubble === "boolean") {
   2869            data.event.cancelBubble = true;
   2870        }
   2871    },
   2872 
   2873    /**
   2874     * The flag to indicate cancellation state.
   2875     * @type {boolean}
   2876     * @deprecated
   2877     */
   2878    get returnValue() {
   2879        return !pd(this).canceled
   2880    },
   2881    set returnValue(value) {
   2882        if (!value) {
   2883            setCancelFlag(pd(this));
   2884        }
   2885    },
   2886 
   2887    /**
   2888     * Initialize this event object. But do nothing under event dispatching.
   2889     * @param {string} type The event type.
   2890     * @param {boolean} [bubbles=false] The flag to be possible to bubble up.
   2891     * @param {boolean} [cancelable=false] The flag to be possible to cancel.
   2892     * @deprecated
   2893     */
   2894    initEvent() {
   2895        // Do nothing.
   2896    },
   2897 };
   2898 
   2899 // `constructor` is not enumerable.
   2900 Object.defineProperty(Event.prototype, "constructor", {
   2901    value: Event,
   2902    configurable: true,
   2903    writable: true,
   2904 });
   2905 
   2906 // Ensure `event instanceof window.Event` is `true`.
   2907 if (typeof window !== "undefined" && typeof window.Event !== "undefined") {
   2908    Object.setPrototypeOf(Event.prototype, window.Event.prototype);
   2909 
   2910    // Make association for wrappers.
   2911    wrappers.set(window.Event.prototype, Event);
   2912 }
   2913 
   2914 /**
   2915 * Get the property descriptor to redirect a given property.
   2916 * @param {string} key Property name to define property descriptor.
   2917 * @returns {PropertyDescriptor} The property descriptor to redirect the property.
   2918 * @private
   2919 */
   2920 function defineRedirectDescriptor(key) {
   2921    return {
   2922        get() {
   2923            return pd(this).event[key]
   2924        },
   2925        set(value) {
   2926            pd(this).event[key] = value;
   2927        },
   2928        configurable: true,
   2929        enumerable: true,
   2930    }
   2931 }
   2932 
   2933 /**
   2934 * Get the property descriptor to call a given method property.
   2935 * @param {string} key Property name to define property descriptor.
   2936 * @returns {PropertyDescriptor} The property descriptor to call the method property.
   2937 * @private
   2938 */
   2939 function defineCallDescriptor(key) {
   2940    return {
   2941        value() {
   2942            const event = pd(this).event;
   2943            return event[key].apply(event, arguments)
   2944        },
   2945        configurable: true,
   2946        enumerable: true,
   2947    }
   2948 }
   2949 
   2950 /**
   2951 * Define new wrapper class.
   2952 * @param {Function} BaseEvent The base wrapper class.
   2953 * @param {Object} proto The prototype of the original event.
   2954 * @returns {Function} The defined wrapper class.
   2955 * @private
   2956 */
   2957 function defineWrapper(BaseEvent, proto) {
   2958    const keys = Object.keys(proto);
   2959    if (keys.length === 0) {
   2960        return BaseEvent
   2961    }
   2962 
   2963    /** CustomEvent */
   2964    function CustomEvent(eventTarget, event) {
   2965        BaseEvent.call(this, eventTarget, event);
   2966    }
   2967 
   2968    CustomEvent.prototype = Object.create(BaseEvent.prototype, {
   2969        constructor: { value: CustomEvent, configurable: true, writable: true },
   2970    });
   2971 
   2972    // Define accessors.
   2973    for (let i = 0; i < keys.length; ++i) {
   2974        const key = keys[i];
   2975        if (!(key in BaseEvent.prototype)) {
   2976            const descriptor = Object.getOwnPropertyDescriptor(proto, key);
   2977            const isFunc = typeof descriptor.value === "function";
   2978            Object.defineProperty(
   2979                CustomEvent.prototype,
   2980                key,
   2981                isFunc
   2982                    ? defineCallDescriptor(key)
   2983                    : defineRedirectDescriptor(key)
   2984            );
   2985        }
   2986    }
   2987 
   2988    return CustomEvent
   2989 }
   2990 
   2991 /**
   2992 * Get the wrapper class of a given prototype.
   2993 * @param {Object} proto The prototype of the original event to get its wrapper.
   2994 * @returns {Function} The wrapper class.
   2995 * @private
   2996 */
   2997 function getWrapper(proto) {
   2998    if (proto == null || proto === Object.prototype) {
   2999        return Event
   3000    }
   3001 
   3002    let wrapper = wrappers.get(proto);
   3003    if (wrapper == null) {
   3004        wrapper = defineWrapper(getWrapper(Object.getPrototypeOf(proto)), proto);
   3005        wrappers.set(proto, wrapper);
   3006    }
   3007    return wrapper
   3008 }
   3009 
   3010 /**
   3011 * Wrap a given event to management a dispatching.
   3012 * @param {EventTarget} eventTarget The event target of this dispatching.
   3013 * @param {Object} event The event to wrap.
   3014 * @returns {Event} The wrapper instance.
   3015 * @private
   3016 */
   3017 function wrapEvent(eventTarget, event) {
   3018    const Wrapper = getWrapper(Object.getPrototypeOf(event));
   3019    return new Wrapper(eventTarget, event)
   3020 }
   3021 
   3022 /**
   3023 * Get the immediateStopped flag of a given event.
   3024 * @param {Event} event The event to get.
   3025 * @returns {boolean} The flag to stop propagation immediately.
   3026 * @private
   3027 */
   3028 function isStopped(event) {
   3029    return pd(event).immediateStopped
   3030 }
   3031 
   3032 /**
   3033 * Set the current event phase of a given event.
   3034 * @param {Event} event The event to set current target.
   3035 * @param {number} eventPhase New event phase.
   3036 * @returns {void}
   3037 * @private
   3038 */
   3039 function setEventPhase(event, eventPhase) {
   3040    pd(event).eventPhase = eventPhase;
   3041 }
   3042 
   3043 /**
   3044 * Set the current target of a given event.
   3045 * @param {Event} event The event to set current target.
   3046 * @param {EventTarget|null} currentTarget New current target.
   3047 * @returns {void}
   3048 * @private
   3049 */
   3050 function setCurrentTarget(event, currentTarget) {
   3051    pd(event).currentTarget = currentTarget;
   3052 }
   3053 
   3054 /**
   3055 * Set a passive listener of a given event.
   3056 * @param {Event} event The event to set current target.
   3057 * @param {Function|null} passiveListener New passive listener.
   3058 * @returns {void}
   3059 * @private
   3060 */
   3061 function setPassiveListener(event, passiveListener) {
   3062    pd(event).passiveListener = passiveListener;
   3063 }
   3064 
   3065 /**
   3066 * @typedef {object} ListenerNode
   3067 * @property {Function} listener
   3068 * @property {1|2|3} listenerType
   3069 * @property {boolean} passive
   3070 * @property {boolean} once
   3071 * @property {ListenerNode|null} next
   3072 * @private
   3073 */
   3074 
   3075 /**
   3076 * @type {WeakMap<object, Map<string, ListenerNode>>}
   3077 * @private
   3078 */
   3079 const listenersMap = new WeakMap();
   3080 
   3081 // Listener types
   3082 const CAPTURE = 1;
   3083 const BUBBLE = 2;
   3084 const ATTRIBUTE = 3;
   3085 
   3086 /**
   3087 * Check whether a given value is an object or not.
   3088 * @param {any} x The value to check.
   3089 * @returns {boolean} `true` if the value is an object.
   3090 */
   3091 function isObject(x) {
   3092    return x !== null && typeof x === "object" //eslint-disable-line no-restricted-syntax
   3093 }
   3094 
   3095 /**
   3096 * Get listeners.
   3097 * @param {EventTarget} eventTarget The event target to get.
   3098 * @returns {Map<string, ListenerNode>} The listeners.
   3099 * @private
   3100 */
   3101 function getListeners(eventTarget) {
   3102    const listeners = listenersMap.get(eventTarget);
   3103    if (listeners == null) {
   3104        throw new TypeError(
   3105            "'this' is expected an EventTarget object, but got another value."
   3106        )
   3107    }
   3108    return listeners
   3109 }
   3110 
   3111 /**
   3112 * Get the property descriptor for the event attribute of a given event.
   3113 * @param {string} eventName The event name to get property descriptor.
   3114 * @returns {PropertyDescriptor} The property descriptor.
   3115 * @private
   3116 */
   3117 function defineEventAttributeDescriptor(eventName) {
   3118    return {
   3119        get() {
   3120            const listeners = getListeners(this);
   3121            let node = listeners.get(eventName);
   3122            while (node != null) {
   3123                if (node.listenerType === ATTRIBUTE) {
   3124                    return node.listener
   3125                }
   3126                node = node.next;
   3127            }
   3128            return null
   3129        },
   3130 
   3131        set(listener) {
   3132            if (typeof listener !== "function" && !isObject(listener)) {
   3133                listener = null; // eslint-disable-line no-param-reassign
   3134            }
   3135            const listeners = getListeners(this);
   3136 
   3137            // Traverse to the tail while removing old value.
   3138            let prev = null;
   3139            let node = listeners.get(eventName);
   3140            while (node != null) {
   3141                if (node.listenerType === ATTRIBUTE) {
   3142                    // Remove old value.
   3143                    if (prev !== null) {
   3144                        prev.next = node.next;
   3145                    } else if (node.next !== null) {
   3146                        listeners.set(eventName, node.next);
   3147                    } else {
   3148                        listeners.delete(eventName);
   3149                    }
   3150                } else {
   3151                    prev = node;
   3152                }
   3153 
   3154                node = node.next;
   3155            }
   3156 
   3157            // Add new value.
   3158            if (listener !== null) {
   3159                const newNode = {
   3160                    listener,
   3161                    listenerType: ATTRIBUTE,
   3162                    passive: false,
   3163                    once: false,
   3164                    next: null,
   3165                };
   3166                if (prev === null) {
   3167                    listeners.set(eventName, newNode);
   3168                } else {
   3169                    prev.next = newNode;
   3170                }
   3171            }
   3172        },
   3173        configurable: true,
   3174        enumerable: true,
   3175    }
   3176 }
   3177 
   3178 /**
   3179 * Define an event attribute (e.g. `eventTarget.onclick`).
   3180 * @param {Object} eventTargetPrototype The event target prototype to define an event attrbite.
   3181 * @param {string} eventName The event name to define.
   3182 * @returns {void}
   3183 */
   3184 function defineEventAttribute(eventTargetPrototype, eventName) {
   3185    Object.defineProperty(
   3186        eventTargetPrototype,
   3187        `on${eventName}`,
   3188        defineEventAttributeDescriptor(eventName)
   3189    );
   3190 }
   3191 
   3192 /**
   3193 * Define a custom EventTarget with event attributes.
   3194 * @param {string[]} eventNames Event names for event attributes.
   3195 * @returns {EventTarget} The custom EventTarget.
   3196 * @private
   3197 */
   3198 function defineCustomEventTarget(eventNames) {
   3199    /** CustomEventTarget */
   3200    function CustomEventTarget() {
   3201        EventTarget.call(this);
   3202    }
   3203 
   3204    CustomEventTarget.prototype = Object.create(EventTarget.prototype, {
   3205        constructor: {
   3206            value: CustomEventTarget,
   3207            configurable: true,
   3208            writable: true,
   3209        },
   3210    });
   3211 
   3212    for (let i = 0; i < eventNames.length; ++i) {
   3213        defineEventAttribute(CustomEventTarget.prototype, eventNames[i]);
   3214    }
   3215 
   3216    return CustomEventTarget
   3217 }
   3218 
   3219 /**
   3220 * EventTarget.
   3221 *
   3222 * - This is constructor if no arguments.
   3223 * - This is a function which returns a CustomEventTarget constructor if there are arguments.
   3224 *
   3225 * For example:
   3226 *
   3227 *     class A extends EventTarget {}
   3228 *     class B extends EventTarget("message") {}
   3229 *     class C extends EventTarget("message", "error") {}
   3230 *     class D extends EventTarget(["message", "error"]) {}
   3231 */
   3232 function EventTarget() {
   3233    /*eslint-disable consistent-return */
   3234    if (this instanceof EventTarget) {
   3235        listenersMap.set(this, new Map());
   3236        return
   3237    }
   3238    if (arguments.length === 1 && Array.isArray(arguments[0])) {
   3239        return defineCustomEventTarget(arguments[0])
   3240    }
   3241    if (arguments.length > 0) {
   3242        const types = new Array(arguments.length);
   3243        for (let i = 0; i < arguments.length; ++i) {
   3244            types[i] = arguments[i];
   3245        }
   3246        return defineCustomEventTarget(types)
   3247    }
   3248    throw new TypeError("Cannot call a class as a function")
   3249    /*eslint-enable consistent-return */
   3250 }
   3251 
   3252 // Should be enumerable, but class methods are not enumerable.
   3253 EventTarget.prototype = {
   3254    /**
   3255     * Add a given listener to this event target.
   3256     * @param {string} eventName The event name to add.
   3257     * @param {Function} listener The listener to add.
   3258     * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
   3259     * @returns {void}
   3260     */
   3261    addEventListener(eventName, listener, options) {
   3262        if (listener == null) {
   3263            return
   3264        }
   3265        if (typeof listener !== "function" && !isObject(listener)) {
   3266            throw new TypeError("'listener' should be a function or an object.")
   3267        }
   3268 
   3269        const listeners = getListeners(this);
   3270        const optionsIsObj = isObject(options);
   3271        const capture = optionsIsObj
   3272            ? Boolean(options.capture)
   3273            : Boolean(options);
   3274        const listenerType = capture ? CAPTURE : BUBBLE;
   3275        const newNode = {
   3276            listener,
   3277            listenerType,
   3278            passive: optionsIsObj && Boolean(options.passive),
   3279            once: optionsIsObj && Boolean(options.once),
   3280            next: null,
   3281        };
   3282 
   3283        // Set it as the first node if the first node is null.
   3284        let node = listeners.get(eventName);
   3285        if (node === undefined) {
   3286            listeners.set(eventName, newNode);
   3287            return
   3288        }
   3289 
   3290        // Traverse to the tail while checking duplication..
   3291        let prev = null;
   3292        while (node != null) {
   3293            if (
   3294                node.listener === listener &&
   3295                node.listenerType === listenerType
   3296            ) {
   3297                // Should ignore duplication.
   3298                return
   3299            }
   3300            prev = node;
   3301            node = node.next;
   3302        }
   3303 
   3304        // Add it.
   3305        prev.next = newNode;
   3306    },
   3307 
   3308    /**
   3309     * Remove a given listener from this event target.
   3310     * @param {string} eventName The event name to remove.
   3311     * @param {Function} listener The listener to remove.
   3312     * @param {boolean|{capture?:boolean,passive?:boolean,once?:boolean}} [options] The options for this listener.
   3313     * @returns {void}
   3314     */
   3315    removeEventListener(eventName, listener, options) {
   3316        if (listener == null) {
   3317            return
   3318        }
   3319 
   3320        const listeners = getListeners(this);
   3321        const capture = isObject(options)
   3322            ? Boolean(options.capture)
   3323            : Boolean(options);
   3324        const listenerType = capture ? CAPTURE : BUBBLE;
   3325 
   3326        let prev = null;
   3327        let node = listeners.get(eventName);
   3328        while (node != null) {
   3329            if (
   3330                node.listener === listener &&
   3331                node.listenerType === listenerType
   3332            ) {
   3333                if (prev !== null) {
   3334                    prev.next = node.next;
   3335                } else if (node.next !== null) {
   3336                    listeners.set(eventName, node.next);
   3337                } else {
   3338                    listeners.delete(eventName);
   3339                }
   3340                return
   3341            }
   3342 
   3343            prev = node;
   3344            node = node.next;
   3345        }
   3346    },
   3347 
   3348    /**
   3349     * Dispatch a given event.
   3350     * @param {Event|{type:string}} event The event to dispatch.
   3351     * @returns {boolean} `false` if canceled.
   3352     */
   3353    dispatchEvent(event) {
   3354        if (event == null || typeof event.type !== "string") {
   3355            throw new TypeError('"event.type" should be a string.')
   3356        }
   3357 
   3358        // If listeners aren't registered, terminate.
   3359        const listeners = getListeners(this);
   3360        const eventName = event.type;
   3361        let node = listeners.get(eventName);
   3362        if (node == null) {
   3363            return true
   3364        }
   3365 
   3366        // Since we cannot rewrite several properties, so wrap object.
   3367        const wrappedEvent = wrapEvent(this, event);
   3368 
   3369        // This doesn't process capturing phase and bubbling phase.
   3370        // This isn't participating in a tree.
   3371        let prev = null;
   3372        while (node != null) {
   3373            // Remove this listener if it's once
   3374            if (node.once) {
   3375                if (prev !== null) {
   3376                    prev.next = node.next;
   3377                } else if (node.next !== null) {
   3378                    listeners.set(eventName, node.next);
   3379                } else {
   3380                    listeners.delete(eventName);
   3381                }
   3382            } else {
   3383                prev = node;
   3384            }
   3385 
   3386            // Call this listener
   3387            setPassiveListener(
   3388                wrappedEvent,
   3389                node.passive ? node.listener : null
   3390            );
   3391            if (typeof node.listener === "function") {
   3392                try {
   3393                    node.listener.call(this, wrappedEvent);
   3394                } catch (err) {
   3395                    if (
   3396                        typeof console !== "undefined" &&
   3397                        typeof console.error === "function"
   3398                    ) {
   3399                        console.error(err);
   3400                    }
   3401                }
   3402            } else if (
   3403                node.listenerType !== ATTRIBUTE &&
   3404                typeof node.listener.handleEvent === "function"
   3405            ) {
   3406                node.listener.handleEvent(wrappedEvent);
   3407            }
   3408 
   3409            // Break if `event.stopImmediatePropagation` was called.
   3410            if (isStopped(wrappedEvent)) {
   3411                break
   3412            }
   3413 
   3414            node = node.next;
   3415        }
   3416        setPassiveListener(wrappedEvent, null);
   3417        setEventPhase(wrappedEvent, 0);
   3418        setCurrentTarget(wrappedEvent, null);
   3419 
   3420        return !wrappedEvent.defaultPrevented
   3421    },
   3422 };
   3423 
   3424 // `constructor` is not enumerable.
   3425 Object.defineProperty(EventTarget.prototype, "constructor", {
   3426    value: EventTarget,
   3427    configurable: true,
   3428    writable: true,
   3429 });
   3430 
   3431 // Ensure `eventTarget instanceof window.EventTarget` is `true`.
   3432 if (
   3433    typeof window !== "undefined" &&
   3434    typeof window.EventTarget !== "undefined"
   3435 ) {
   3436    Object.setPrototypeOf(EventTarget.prototype, window.EventTarget.prototype);
   3437 }
   3438 
   3439 /* harmony default export */ var event_target_shim = (EventTarget);
   3440 
   3441 
   3442 // CONCATENATED MODULE: ./src/index.js
   3443 /* This Source Code Form is subject to the terms of the Mozilla Public
   3444 * License, v. 2.0. If a copy of the MPL was not distributed with this
   3445 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
   3446 
   3447 // A wrapper that combines a WebSocket to the channelserver
   3448 // with some client-side encryption for securing the channel.
   3449 //
   3450 // This code is responsible for the event handling and the consumer API.
   3451 // All the details of encrypting the messages are delegated to`./tlsconnection.js`.
   3452 
   3453 
   3454 
   3455 
   3456 
   3457 
   3458 
   3459 const CLOSE_FLUSH_BUFFER_INTERVAL_MS = 200;
   3460 const CLOSE_FLUSH_BUFFER_MAX_TRIES = 5;
   3461 
   3462 class src_PairingChannel extends EventTarget {
   3463  constructor(channelId, channelKey, socket, connection) {
   3464    super();
   3465    this._channelId = channelId;
   3466    this._channelKey = channelKey;
   3467    this._socket = socket;
   3468    this._connection = connection;
   3469    this._selfClosed = false;
   3470    this._peerClosed = false;
   3471    this._setupListeners();
   3472  }
   3473 
   3474  /**
   3475   * Create a new pairing channel.
   3476   *
   3477   * This will open a channel on the channelserver, and generate a random client-side
   3478   * encryption key. When the promise resolves, `this.channelId` and `this.channelKey`
   3479   * can be transferred to another client to allow it to securely connect to the channel.
   3480   *
   3481   * @returns Promise<PairingChannel>
   3482   */
   3483  static create(channelServerURI) {
   3484    const wsURI = new URL('/v1/ws/', channelServerURI).href;
   3485    const channelKey = crypto.getRandomValues(new Uint8Array(32));
   3486    // The one who creates the channel plays the role of 'server' in the underlying TLS exchange.
   3487    return this._makePairingChannel(wsURI, tlsconnection_ServerConnection, channelKey);
   3488  }
   3489 
   3490  /**
   3491   * Connect to an existing pairing channel.
   3492   *
   3493   * This will connect to a channel on the channelserver previously established by
   3494   * another client calling `create`. The `channelId` and `channelKey` must have been
   3495   * obtained via some out-of-band mechanism (such as by scanning from a QR code).
   3496   *
   3497   * @returns Promise<PairingChannel>
   3498   */
   3499  static connect(channelServerURI, channelId, channelKey) {
   3500    const wsURI = new URL(`/v1/ws/${channelId}`, channelServerURI).href;
   3501    // The one who connects to an existing channel plays the role of 'client'
   3502    // in the underlying TLS exchange.
   3503    return this._makePairingChannel(wsURI, tlsconnection_ClientConnection, channelKey);
   3504  }
   3505 
   3506  static _makePairingChannel(wsUri, ConnectionClass, psk) {
   3507    const socket = new WebSocket(wsUri);
   3508    return new Promise((resolve, reject) => {
   3509      // eslint-disable-next-line prefer-const
   3510      let stopListening;
   3511      const onConnectionError = async () => {
   3512        stopListening();
   3513        reject(new Error('Error while creating the pairing channel'));
   3514      };
   3515      const onFirstMessage = async event => {
   3516        stopListening();
   3517        try {
   3518          // The channelserver echos back the channel id, and we use it as an
   3519          // additional input to the TLS handshake via the "psk id" field.
   3520          const {channelid: channelId} = JSON.parse(event.data);
   3521          const pskId = utf8ToBytes(channelId);
   3522          const connection = await ConnectionClass.create(psk, pskId, data => {
   3523            // Send data by forwarding it via the channelserver websocket.
   3524            // The TLS connection gives us `data` as raw bytes, but channelserver
   3525            // expects b64urlsafe strings, because it wraps them in a JSON object envelope.
   3526            socket.send(bytesToBase64url(data));
   3527          });
   3528          const instance = new this(channelId, psk, socket, connection);
   3529          resolve(instance);
   3530        } catch (err) {
   3531          reject(err);
   3532        }
   3533      };
   3534      stopListening = () => {
   3535        socket.removeEventListener('close', onConnectionError);
   3536        socket.removeEventListener('error', onConnectionError);
   3537        socket.removeEventListener('message', onFirstMessage);
   3538      };
   3539      socket.addEventListener('close', onConnectionError);
   3540      socket.addEventListener('error', onConnectionError);
   3541      socket.addEventListener('message', onFirstMessage);
   3542    });
   3543  }
   3544 
   3545  _setupListeners() {
   3546    this._socket.addEventListener('message', async event => {
   3547      try {
   3548        // When we receive data from the channelserver, pump it through the TLS connection
   3549        // to decrypt it, then echo it back out to consumers as an event.
   3550        const channelServerEnvelope = JSON.parse(event.data);
   3551        const payload = await this._connection.recv(base64urlToBytes(channelServerEnvelope.message));
   3552        if (payload !== null) {
   3553          const data = JSON.parse(bytesToUtf8(payload));
   3554          this.dispatchEvent(new CustomEvent('message', {
   3555            detail: {
   3556              data,
   3557              sender: channelServerEnvelope.sender,
   3558            },
   3559          }));
   3560        }
   3561      } catch (error) {
   3562        let event;
   3563        // The underlying TLS connection will signal a clean shutdown of the channel
   3564        // by throwing a special error, because it doesn't really have a better
   3565        // signally mechanism available.
   3566        if (error instanceof TLSCloseNotify) {
   3567          this._peerClosed = true;
   3568          if (this._selfClosed) {
   3569            this._shutdown();
   3570          }
   3571          event = new CustomEvent('close');
   3572        } else {
   3573          event = new CustomEvent('error', {
   3574            detail: {
   3575              error,
   3576            }
   3577          });
   3578        }
   3579        this.dispatchEvent(event);
   3580      }
   3581    });
   3582    // Relay the WebSocket events.
   3583    this._socket.addEventListener('error', () => {
   3584      this._shutdown();
   3585      // The dispatched event that we receive has no useful information.
   3586      this.dispatchEvent(new CustomEvent('error', {
   3587        detail: {
   3588          error: new Error('WebSocket error.'),
   3589        },
   3590      }));
   3591    });
   3592    // In TLS, the peer has to explicitly send a close notification,
   3593    // which we dispatch above.  Unexpected socket close is an error.
   3594    this._socket.addEventListener('close', () => {
   3595      this._shutdown();
   3596      if (! this._peerClosed) {
   3597        this.dispatchEvent(new CustomEvent('error', {
   3598          detail: {
   3599            error: new Error('WebSocket unexpectedly closed'),
   3600          }
   3601        }));
   3602      }
   3603    });
   3604  }
   3605 
   3606  /**
   3607   * @param {Object} data
   3608   */
   3609  async send(data) {
   3610    const payload = utf8ToBytes(JSON.stringify(data));
   3611    await this._connection.send(payload);
   3612  }
   3613 
   3614  async close() {
   3615    this._selfClosed = true;
   3616    await this._connection.close();
   3617    try {
   3618      // Ensure all queued bytes have been sent before closing the connection.
   3619      let tries = 0;
   3620      while (this._socket.bufferedAmount > 0) {
   3621        if (++tries > CLOSE_FLUSH_BUFFER_MAX_TRIES) {
   3622          throw new Error('Could not flush the outgoing buffer in time.');
   3623        }
   3624        await new Promise(res => setTimeout(res, CLOSE_FLUSH_BUFFER_INTERVAL_MS));
   3625      }
   3626    } finally {
   3627      // If the peer hasn't closed, we might still receive some data.
   3628      if (this._peerClosed) {
   3629        this._shutdown();
   3630      }
   3631    }
   3632  }
   3633 
   3634  _shutdown() {
   3635    if (this._socket) {
   3636      this._socket.close();
   3637      this._socket = null;
   3638      this._connection = null;
   3639    }
   3640  }
   3641 
   3642  get closed() {
   3643    return (! this._socket) || (this._socket.readyState === 3);
   3644  }
   3645 
   3646  get channelId() {
   3647    return this._channelId;
   3648  }
   3649 
   3650  get channelKey() {
   3651    return this._channelKey;
   3652  }
   3653 }
   3654 
   3655 // Re-export helpful utilities for calling code to use.
   3656 
   3657 
   3658 // For running tests using the built bundle,
   3659 // expose a bunch of implementation details.
   3660 
   3661 
   3662 
   3663 
   3664 
   3665 
   3666 
   3667 const _internals = {
   3668  arrayToBytes: arrayToBytes,
   3669  BufferReader: utils_BufferReader,
   3670  BufferWriter: utils_BufferWriter,
   3671  bytesAreEqual: bytesAreEqual,
   3672  bytesToHex: bytesToHex,
   3673  bytesToUtf8: bytesToUtf8,
   3674  ClientConnection: tlsconnection_ClientConnection,
   3675  Connection: tlsconnection_Connection,
   3676  DecryptionState: recordlayer_DecryptionState,
   3677  EncryptedExtensions: EncryptedExtensions,
   3678  EncryptionState: recordlayer_EncryptionState,
   3679  Finished: messages_Finished,
   3680  HASH_LENGTH: HASH_LENGTH,
   3681  hexToBytes: hexToBytes,
   3682  hkdfExpand: hkdfExpand,
   3683  KeySchedule: keyschedule_KeySchedule,
   3684  NewSessionTicket: messages_NewSessionTicket,
   3685  RecordLayer: recordlayer_RecordLayer,
   3686  ServerConnection: tlsconnection_ServerConnection,
   3687  utf8ToBytes: utf8ToBytes,
   3688  zeros: zeros,
   3689 };
   3690 
   3691 
   3692 /***/ })
   3693 /******/ ])["PairingChannel"];
   3694 
   3695 // Keep the windowless browser alive, so that WebSocket doesn't become a
   3696 // dead wrapper.
   3697 FxAccountsPairingChannel._browser = browser;