@novnc/novnc
Advanced tools
Comparing version 1.4.0-beta-gb76358e to 1.4.0-g295004c
@@ -34,6 +34,3 @@ /* | ||
let rQ = sock.rQ; | ||
let rQi = sock.rQi; | ||
let subencoding = rQ[rQi]; // Peek | ||
let subencoding = sock.rQpeek8(); | ||
if (subencoding > 30) { // Raw | ||
@@ -69,3 +66,3 @@ throw new Error("Illegal hextile subencoding (subencoding: " + | ||
let subrects = rQ[rQi + bytes - 1]; // Peek | ||
let subrects = sock.rQpeekBytes(bytes).at(-1); | ||
if (subencoding & 0x10) { // SubrectsColoured | ||
@@ -84,3 +81,3 @@ bytes += subrects * (4 + 2); | ||
// We know the encoding and have a whole tile | ||
rQi++; | ||
sock.rQshift8(); | ||
if (subencoding === 0) { | ||
@@ -95,16 +92,14 @@ if (this._lastsubencoding & 0x01) { | ||
let pixels = tw * th; | ||
let data = sock.rQshiftBytes(pixels * 4, false); | ||
// Max sure the image is fully opaque | ||
for (let i = 0;i < pixels;i++) { | ||
rQ[rQi + i * 4 + 3] = 255; | ||
data[i * 4 + 3] = 255; | ||
} | ||
display.blitImage(tx, ty, tw, th, rQ, rQi); | ||
rQi += bytes - 1; | ||
display.blitImage(tx, ty, tw, th, data, 0); | ||
} else { | ||
if (subencoding & 0x02) { // Background | ||
this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
this._background = new Uint8Array(sock.rQshiftBytes(4)); | ||
} | ||
if (subencoding & 0x04) { // Foreground | ||
this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
this._foreground = new Uint8Array(sock.rQshiftBytes(4)); | ||
} | ||
@@ -114,4 +109,3 @@ | ||
if (subencoding & 0x08) { // AnySubrects | ||
let subrects = rQ[rQi]; | ||
rQi++; | ||
let subrects = sock.rQshift8(); | ||
@@ -121,14 +115,11 @@ for (let s = 0; s < subrects; s++) { | ||
if (subencoding & 0x10) { // SubrectsColoured | ||
color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
color = sock.rQshiftBytes(4); | ||
} else { | ||
color = this._foreground; | ||
} | ||
const xy = rQ[rQi]; | ||
rQi++; | ||
const xy = sock.rQshift8(); | ||
const sx = (xy >> 4); | ||
const sy = (xy & 0x0f); | ||
const wh = rQ[rQi]; | ||
rQi++; | ||
const wh = sock.rQshift8(); | ||
const sw = (wh >> 4) + 1; | ||
@@ -142,3 +133,2 @@ const sh = (wh & 0x0f) + 1; | ||
} | ||
sock.rQi = rQi; | ||
this._lastsubencoding = subencoding; | ||
@@ -145,0 +135,0 @@ this._tiles--; |
@@ -14,8 +14,5 @@ /* | ||
// and Huffman tables, so we need to cache them. | ||
this._quantTables = []; | ||
this._huffmanTables = []; | ||
this._cachedQuantTables = []; | ||
this._cachedHuffmanTables = []; | ||
this._jpegLength = 0; | ||
this._segments = []; | ||
@@ -26,118 +23,126 @@ } | ||
// A rect of JPEG encodings is simply a JPEG file | ||
if (!this._parseJPEG(sock.rQslice(0))) { | ||
return false; | ||
} | ||
const data = sock.rQshiftBytes(this._jpegLength); | ||
if (this._quantTables.length != 0 && this._huffmanTables.length != 0) { | ||
// If there are quantization tables and Huffman tables in the JPEG | ||
// image, we can directly render it. | ||
display.imageRect(x, y, width, height, "image/jpeg", data); | ||
return true; | ||
} else { | ||
// Otherwise we need to insert cached tables. | ||
const sofIndex = this._segments.findIndex( | ||
x => x[1] == 0xC0 || x[1] == 0xC2 | ||
); | ||
if (sofIndex == -1) { | ||
throw new Error("Illegal JPEG image without SOF"); | ||
while (true) { | ||
let segment = this._readSegment(sock); | ||
if (segment === null) { | ||
return false; | ||
} | ||
let segments = this._segments.slice(0, sofIndex); | ||
segments = segments.concat(this._quantTables.length ? | ||
this._quantTables : | ||
this._cachedQuantTables); | ||
segments.push(this._segments[sofIndex]); | ||
segments = segments.concat(this._huffmanTables.length ? | ||
this._huffmanTables : | ||
this._cachedHuffmanTables, | ||
this._segments.slice(sofIndex + 1)); | ||
let length = 0; | ||
for (let i = 0; i < segments.length; i++) { | ||
length += segments[i].length; | ||
this._segments.push(segment); | ||
// End of image? | ||
if (segment[1] === 0xD9) { | ||
break; | ||
} | ||
const data = new Uint8Array(length); | ||
length = 0; | ||
for (let i = 0; i < segments.length; i++) { | ||
data.set(segments[i], length); | ||
length += segments[i].length; | ||
} | ||
let huffmanTables = []; | ||
let quantTables = []; | ||
for (let segment of this._segments) { | ||
let type = segment[1]; | ||
if (type === 0xC4) { | ||
// Huffman tables | ||
huffmanTables.push(segment); | ||
} else if (type === 0xDB) { | ||
// Quantization tables | ||
quantTables.push(segment); | ||
} | ||
display.imageRect(x, y, width, height, "image/jpeg", data); | ||
return true; | ||
} | ||
const sofIndex = this._segments.findIndex( | ||
x => x[1] == 0xC0 || x[1] == 0xC2 | ||
); | ||
if (sofIndex == -1) { | ||
throw new Error("Illegal JPEG image without SOF"); | ||
} | ||
if (quantTables.length === 0) { | ||
this._segments.splice(sofIndex+1, 0, | ||
...this._cachedQuantTables); | ||
} | ||
if (huffmanTables.length === 0) { | ||
this._segments.splice(sofIndex+1, 0, | ||
...this._cachedHuffmanTables); | ||
} | ||
let length = 0; | ||
for (let segment of this._segments) { | ||
length += segment.length; | ||
} | ||
let data = new Uint8Array(length); | ||
length = 0; | ||
for (let segment of this._segments) { | ||
data.set(segment, length); | ||
length += segment.length; | ||
} | ||
display.imageRect(x, y, width, height, "image/jpeg", data); | ||
if (huffmanTables.length !== 0) { | ||
this._cachedHuffmanTables = huffmanTables; | ||
} | ||
if (quantTables.length !== 0) { | ||
this._cachedQuantTables = quantTables; | ||
} | ||
this._segments = []; | ||
return true; | ||
} | ||
_parseJPEG(buffer) { | ||
if (this._quantTables.length != 0) { | ||
this._cachedQuantTables = this._quantTables; | ||
_readSegment(sock) { | ||
if (sock.rQwait("JPEG", 2)) { | ||
return null; | ||
} | ||
if (this._huffmanTables.length != 0) { | ||
this._cachedHuffmanTables = this._huffmanTables; | ||
let marker = sock.rQshift8(); | ||
if (marker != 0xFF) { | ||
throw new Error("Illegal JPEG marker received (byte: " + | ||
marker + ")"); | ||
} | ||
this._quantTables = []; | ||
this._huffmanTables = []; | ||
this._segments = []; | ||
let i = 0; | ||
let bufferLength = buffer.length; | ||
while (true) { | ||
let j = i; | ||
if (j + 2 > bufferLength) { | ||
return false; | ||
} | ||
if (buffer[j] != 0xFF) { | ||
throw new Error("Illegal JPEG marker received (byte: " + | ||
buffer[j] + ")"); | ||
} | ||
const type = buffer[j+1]; | ||
j += 2; | ||
if (type == 0xD9) { | ||
this._jpegLength = j; | ||
this._segments.push(buffer.slice(i, j)); | ||
return true; | ||
} else if (type == 0xDA) { | ||
// start of scan | ||
let hasFoundEndOfScan = false; | ||
for (let k = j + 3; k + 1 < bufferLength; k++) { | ||
if (buffer[k] == 0xFF && buffer[k+1] != 0x00 && | ||
!(buffer[k+1] >= 0xD0 && buffer[k+1] <= 0xD7)) { | ||
j = k; | ||
hasFoundEndOfScan = true; | ||
break; | ||
} | ||
let type = sock.rQshift8(); | ||
if (type >= 0xD0 && type <= 0xD9 || type == 0x01) { | ||
// No length after marker | ||
return new Uint8Array([marker, type]); | ||
} | ||
if (sock.rQwait("JPEG", 2, 2)) { | ||
return null; | ||
} | ||
let length = sock.rQshift16(); | ||
if (length < 2) { | ||
throw new Error("Illegal JPEG length received (length: " + | ||
length + ")"); | ||
} | ||
if (sock.rQwait("JPEG", length-2, 4)) { | ||
return null; | ||
} | ||
let extra = 0; | ||
if (type === 0xDA) { | ||
// start of scan | ||
extra += 2; | ||
while (true) { | ||
if (sock.rQwait("JPEG", length-2+extra, 4)) { | ||
return null; | ||
} | ||
if (!hasFoundEndOfScan) { | ||
return false; | ||
let data = sock.rQpeekBytes(length-2+extra, false); | ||
if (data.at(-2) === 0xFF && data.at(-1) !== 0x00 && | ||
!(data.at(-1) >= 0xD0 && data.at(-1) <= 0xD7)) { | ||
extra -= 2; | ||
break; | ||
} | ||
this._segments.push(buffer.slice(i, j)); | ||
i = j; | ||
continue; | ||
} else if (type >= 0xD0 && type < 0xD9 || type == 0x01) { | ||
// No length after marker | ||
this._segments.push(buffer.slice(i, j)); | ||
i = j; | ||
continue; | ||
extra++; | ||
} | ||
if (j + 2 > bufferLength) { | ||
return false; | ||
} | ||
const length = (buffer[j] << 8) + buffer[j+1] - 2; | ||
if (length < 0) { | ||
throw new Error("Illegal JPEG length received (length: " + | ||
length + ")"); | ||
} | ||
j += 2; | ||
if (j + length > bufferLength) { | ||
return false; | ||
} | ||
j += length; | ||
const segment = buffer.slice(i, j); | ||
if (type == 0xC4) { | ||
// Huffman tables | ||
this._huffmanTables.push(segment); | ||
} else if (type == 0xDB) { | ||
// Quantization tables | ||
this._quantTables.push(segment); | ||
} | ||
this._segments.push(segment); | ||
i = j; | ||
} | ||
let segment = new Uint8Array(2 + length + extra); | ||
segment[0] = marker; | ||
segment[1] = type; | ||
segment[2] = length >> 8; | ||
segment[3] = length; | ||
segment.set(sock.rQshiftBytes(length-2+extra, false), 4); | ||
return segment; | ||
} | ||
} |
@@ -27,37 +27,30 @@ /* | ||
if (sock.rQwait("RAW", bytesPerLine)) { | ||
return false; | ||
} | ||
while (this._lines > 0) { | ||
if (sock.rQwait("RAW", bytesPerLine)) { | ||
return false; | ||
} | ||
const curY = y + (height - this._lines); | ||
const currHeight = Math.min(this._lines, | ||
Math.floor(sock.rQlen / bytesPerLine)); | ||
const pixels = width * currHeight; | ||
const curY = y + (height - this._lines); | ||
let data = sock.rQ; | ||
let index = sock.rQi; | ||
let data = sock.rQshiftBytes(bytesPerLine, false); | ||
// Convert data if needed | ||
if (depth == 8) { | ||
const newdata = new Uint8Array(pixels * 4); | ||
for (let i = 0; i < pixels; i++) { | ||
newdata[i * 4 + 0] = ((data[index + i] >> 0) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 1] = ((data[index + i] >> 2) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 2] = ((data[index + i] >> 4) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 3] = 255; | ||
// Convert data if needed | ||
if (depth == 8) { | ||
const newdata = new Uint8Array(width * 4); | ||
for (let i = 0; i < width; i++) { | ||
newdata[i * 4 + 0] = ((data[i] >> 0) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 1] = ((data[i] >> 2) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 2] = ((data[i] >> 4) & 0x3) * 255 / 3; | ||
newdata[i * 4 + 3] = 255; | ||
} | ||
data = newdata; | ||
} | ||
data = newdata; | ||
index = 0; | ||
} | ||
// Max sure the image is fully opaque | ||
for (let i = 0; i < pixels; i++) { | ||
data[index + i * 4 + 3] = 255; | ||
} | ||
// Max sure the image is fully opaque | ||
for (let i = 0; i < width; i++) { | ||
data[i * 4 + 3] = 255; | ||
} | ||
display.blitImage(x, curY, width, currHeight, data, index); | ||
sock.rQskipBytes(currHeight * bytesPerLine); | ||
this._lines -= currHeight; | ||
if (this._lines > 0) { | ||
return false; | ||
display.blitImage(x, curY, width, 1, data, 0); | ||
this._lines--; | ||
} | ||
@@ -64,0 +57,0 @@ |
@@ -79,9 +79,5 @@ /* | ||
const rQi = sock.rQi; | ||
const rQ = sock.rQ; | ||
let pixel = sock.rQshiftBytes(3); | ||
display.fillRect(x, y, width, height, pixel, false); | ||
display.fillRect(x, y, width, height, | ||
[rQ[rQi], rQ[rQi + 1], rQ[rQi + 2]], false); | ||
sock.rQskipBytes(3); | ||
return true; | ||
@@ -320,3 +316,3 @@ } | ||
let data = sock.rQshiftBytes(this._len); | ||
let data = sock.rQshiftBytes(this._len, false); | ||
this._len = 0; | ||
@@ -323,0 +319,0 @@ |
@@ -35,3 +35,3 @@ /* | ||
const data = sock.rQshiftBytes(this._length); | ||
const data = sock.rQshiftBytes(this._length, false); | ||
@@ -38,0 +38,0 @@ this._inflator.setInput(data); |
@@ -18,3 +18,3 @@ /* | ||
this._renderQ = []; // queue drawing actions for in-oder rendering | ||
this._flushing = false; | ||
this._flushPromise = null; | ||
@@ -65,6 +65,2 @@ // the full frame buffer (logical canvas) size | ||
this._clipViewport = false; | ||
// ===== EVENT HANDLERS ===== | ||
this.onflush = () => {}; // A flush request has finished | ||
} | ||
@@ -311,5 +307,10 @@ | ||
if (this._renderQ.length === 0) { | ||
this.onflush(); | ||
return Promise.resolve(); | ||
} else { | ||
this._flushing = true; | ||
if (this._flushPromise === null) { | ||
this._flushPromise = new Promise((resolve) => { | ||
this._flushResolve = resolve; | ||
}); | ||
} | ||
return this._flushPromise; | ||
} | ||
@@ -523,7 +524,9 @@ } | ||
if (this._renderQ.length === 0 && this._flushing) { | ||
this._flushing = false; | ||
this.onflush(); | ||
if (this._renderQ.length === 0 && | ||
this._flushPromise !== null) { | ||
this._flushResolve(); | ||
this._flushPromise = null; | ||
this._flushResolve = null; | ||
} | ||
} | ||
} |
347
core/ra2.js
@@ -1,134 +0,8 @@ | ||
import Base64 from './base64.js'; | ||
import { encodeUTF8 } from './util/strings.js'; | ||
import EventTargetMixin from './util/eventtarget.js'; | ||
import legacyCrypto from './crypto/crypto.js'; | ||
export class AESEAXCipher { | ||
class RA2Cipher { | ||
constructor() { | ||
this._rawKey = null; | ||
this._ctrKey = null; | ||
this._cbcKey = null; | ||
this._zeroBlock = new Uint8Array(16); | ||
this._prefixBlock0 = this._zeroBlock; | ||
this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); | ||
this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); | ||
} | ||
async _encryptBlock(block) { | ||
const encrypted = await window.crypto.subtle.encrypt({ | ||
name: "AES-CBC", | ||
iv: this._zeroBlock, | ||
}, this._cbcKey, block); | ||
return new Uint8Array(encrypted).slice(0, 16); | ||
} | ||
async _initCMAC() { | ||
const k1 = await this._encryptBlock(this._zeroBlock); | ||
const k2 = new Uint8Array(16); | ||
const v = k1[0] >>> 6; | ||
for (let i = 0; i < 15; i++) { | ||
k2[i] = (k1[i + 1] >> 6) | (k1[i] << 2); | ||
k1[i] = (k1[i + 1] >> 7) | (k1[i] << 1); | ||
} | ||
const lut = [0x0, 0x87, 0x0e, 0x89]; | ||
k2[14] ^= v >>> 1; | ||
k2[15] = (k1[15] << 2) ^ lut[v]; | ||
k1[15] = (k1[15] << 1) ^ lut[v >> 1]; | ||
this._k1 = k1; | ||
this._k2 = k2; | ||
} | ||
async _encryptCTR(data, counter) { | ||
const encrypted = await window.crypto.subtle.encrypt({ | ||
"name": "AES-CTR", | ||
counter: counter, | ||
length: 128 | ||
}, this._ctrKey, data); | ||
return new Uint8Array(encrypted); | ||
} | ||
async _decryptCTR(data, counter) { | ||
const decrypted = await window.crypto.subtle.decrypt({ | ||
"name": "AES-CTR", | ||
counter: counter, | ||
length: 128 | ||
}, this._ctrKey, data); | ||
return new Uint8Array(decrypted); | ||
} | ||
async _computeCMAC(data, prefixBlock) { | ||
if (prefixBlock.length !== 16) { | ||
return null; | ||
} | ||
const n = Math.floor(data.length / 16); | ||
const m = Math.ceil(data.length / 16); | ||
const r = data.length - n * 16; | ||
const cbcData = new Uint8Array((m + 1) * 16); | ||
cbcData.set(prefixBlock); | ||
cbcData.set(data, 16); | ||
if (r === 0) { | ||
for (let i = 0; i < 16; i++) { | ||
cbcData[n * 16 + i] ^= this._k1[i]; | ||
} | ||
} else { | ||
cbcData[(n + 1) * 16 + r] = 0x80; | ||
for (let i = 0; i < 16; i++) { | ||
cbcData[(n + 1) * 16 + i] ^= this._k2[i]; | ||
} | ||
} | ||
let cbcEncrypted = await window.crypto.subtle.encrypt({ | ||
name: "AES-CBC", | ||
iv: this._zeroBlock, | ||
}, this._cbcKey, cbcData); | ||
cbcEncrypted = new Uint8Array(cbcEncrypted); | ||
const mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16); | ||
return mac; | ||
} | ||
async setKey(key) { | ||
this._rawKey = key; | ||
this._ctrKey = await window.crypto.subtle.importKey( | ||
"raw", key, {"name": "AES-CTR"}, false, ["encrypt", "decrypt"]); | ||
this._cbcKey = await window.crypto.subtle.importKey( | ||
"raw", key, {"name": "AES-CBC"}, false, ["encrypt", "decrypt"]); | ||
await this._initCMAC(); | ||
} | ||
async encrypt(message, associatedData, nonce) { | ||
const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0); | ||
const encrypted = await this._encryptCTR(message, nCMAC); | ||
const adCMAC = await this._computeCMAC(associatedData, this._prefixBlock1); | ||
const mac = await this._computeCMAC(encrypted, this._prefixBlock2); | ||
for (let i = 0; i < 16; i++) { | ||
mac[i] ^= nCMAC[i] ^ adCMAC[i]; | ||
} | ||
const res = new Uint8Array(16 + encrypted.length); | ||
res.set(encrypted); | ||
res.set(mac, encrypted.length); | ||
return res; | ||
} | ||
async decrypt(encrypted, associatedData, nonce, mac) { | ||
const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0); | ||
const adCMAC = await this._computeCMAC(associatedData, this._prefixBlock1); | ||
const computedMac = await this._computeCMAC(encrypted, this._prefixBlock2); | ||
for (let i = 0; i < 16; i++) { | ||
computedMac[i] ^= nCMAC[i] ^ adCMAC[i]; | ||
} | ||
if (computedMac.length !== mac.length) { | ||
return null; | ||
} | ||
for (let i = 0; i < mac.length; i++) { | ||
if (computedMac[i] !== mac[i]) { | ||
return null; | ||
} | ||
} | ||
const res = await this._decryptCTR(encrypted, nCMAC); | ||
return res; | ||
} | ||
} | ||
export class RA2Cipher { | ||
constructor() { | ||
this._cipher = new AESEAXCipher(); | ||
this._cipher = null; | ||
this._counter = new Uint8Array(16); | ||
@@ -138,3 +12,4 @@ } | ||
async setKey(key) { | ||
await this._cipher.setKey(key); | ||
this._cipher = await legacyCrypto.importKey( | ||
"raw", key, { name: "AES-EAX" }, false, ["encrypt, decrypt"]); | ||
} | ||
@@ -144,3 +19,7 @@ | ||
const ad = new Uint8Array([(message.length & 0xff00) >>> 8, message.length & 0xff]); | ||
const encrypted = await this._cipher.encrypt(message, ad, this._counter); | ||
const encrypted = await legacyCrypto.encrypt({ | ||
name: "AES-EAX", | ||
iv: this._counter, | ||
additionalData: ad, | ||
}, this._cipher, message); | ||
for (let i = 0; i < 16 && this._counter[i]++ === 255; i++); | ||
@@ -153,5 +32,9 @@ const res = new Uint8Array(message.length + 2 + 16); | ||
async receiveMessage(length, encrypted, mac) { | ||
async receiveMessage(length, encrypted) { | ||
const ad = new Uint8Array([(length & 0xff00) >>> 8, length & 0xff]); | ||
const res = await this._cipher.decrypt(encrypted, ad, this._counter, mac); | ||
const res = await legacyCrypto.decrypt({ | ||
name: "AES-EAX", | ||
iv: this._counter, | ||
additionalData: ad, | ||
}, this._cipher, encrypted); | ||
for (let i = 0; i < 16 && this._counter[i]++ === 255; i++); | ||
@@ -162,152 +45,2 @@ return res; | ||
export class RSACipher { | ||
constructor(keyLength) { | ||
this._key = null; | ||
this._keyLength = keyLength; | ||
this._keyBytes = Math.ceil(keyLength / 8); | ||
this._n = null; | ||
this._e = null; | ||
this._d = null; | ||
this._nBigInt = null; | ||
this._eBigInt = null; | ||
this._dBigInt = null; | ||
} | ||
_base64urlDecode(data) { | ||
data = data.replace(/-/g, "+").replace(/_/g, "/"); | ||
data = data.padEnd(Math.ceil(data.length / 4) * 4, "="); | ||
return Base64.decode(data); | ||
} | ||
_u8ArrayToBigInt(arr) { | ||
let hex = '0x'; | ||
for (let i = 0; i < arr.length; i++) { | ||
hex += arr[i].toString(16).padStart(2, '0'); | ||
} | ||
return BigInt(hex); | ||
} | ||
_padArray(arr, length) { | ||
const res = new Uint8Array(length); | ||
res.set(arr, length - arr.length); | ||
return res; | ||
} | ||
_bigIntToU8Array(bigint, padLength=0) { | ||
let hex = bigint.toString(16); | ||
if (padLength === 0) { | ||
padLength = Math.ceil(hex.length / 2) * 2; | ||
} | ||
hex = hex.padStart(padLength * 2, '0'); | ||
const length = hex.length / 2; | ||
const arr = new Uint8Array(length); | ||
for (let i = 0; i < length; i++) { | ||
arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); | ||
} | ||
return arr; | ||
} | ||
_modPow(b, e, m) { | ||
if (m === 1n) { | ||
return 0; | ||
} | ||
let r = 1n; | ||
b = b % m; | ||
while (e > 0) { | ||
if (e % 2n === 1n) { | ||
r = (r * b) % m; | ||
} | ||
e = e / 2n; | ||
b = (b * b) % m; | ||
} | ||
return r; | ||
} | ||
async generateKey() { | ||
this._key = await window.crypto.subtle.generateKey( | ||
{ | ||
name: "RSA-OAEP", | ||
modulusLength: this._keyLength, | ||
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), | ||
hash: {name: "SHA-256"}, | ||
}, | ||
true, ["encrypt", "decrypt"]); | ||
const privateKey = await window.crypto.subtle.exportKey("jwk", this._key.privateKey); | ||
this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes); | ||
this._nBigInt = this._u8ArrayToBigInt(this._n); | ||
this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes); | ||
this._eBigInt = this._u8ArrayToBigInt(this._e); | ||
this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes); | ||
this._dBigInt = this._u8ArrayToBigInt(this._d); | ||
} | ||
setPublicKey(n, e) { | ||
if (n.length !== this._keyBytes || e.length !== this._keyBytes) { | ||
return; | ||
} | ||
this._n = new Uint8Array(this._keyBytes); | ||
this._e = new Uint8Array(this._keyBytes); | ||
this._n.set(n); | ||
this._e.set(e); | ||
this._nBigInt = this._u8ArrayToBigInt(this._n); | ||
this._eBigInt = this._u8ArrayToBigInt(this._e); | ||
} | ||
encrypt(message) { | ||
if (message.length > this._keyBytes - 11) { | ||
return null; | ||
} | ||
const ps = new Uint8Array(this._keyBytes - message.length - 3); | ||
window.crypto.getRandomValues(ps); | ||
for (let i = 0; i < ps.length; i++) { | ||
ps[i] = Math.floor(ps[i] * 254 / 255 + 1); | ||
} | ||
const em = new Uint8Array(this._keyBytes); | ||
em[1] = 0x02; | ||
em.set(ps, 2); | ||
em.set(message, ps.length + 3); | ||
const emBigInt = this._u8ArrayToBigInt(em); | ||
const c = this._modPow(emBigInt, this._eBigInt, this._nBigInt); | ||
return this._bigIntToU8Array(c, this._keyBytes); | ||
} | ||
decrypt(message) { | ||
if (message.length !== this._keyBytes) { | ||
return null; | ||
} | ||
const msgBigInt = this._u8ArrayToBigInt(message); | ||
const emBigInt = this._modPow(msgBigInt, this._dBigInt, this._nBigInt); | ||
const em = this._bigIntToU8Array(emBigInt, this._keyBytes); | ||
if (em[0] !== 0x00 || em[1] !== 0x02) { | ||
return null; | ||
} | ||
let i = 2; | ||
for (; i < em.length; i++) { | ||
if (em[i] === 0x00) { | ||
break; | ||
} | ||
} | ||
if (i === em.length) { | ||
return null; | ||
} | ||
return em.slice(i + 1, em.length); | ||
} | ||
get keyLength() { | ||
return this._keyLength; | ||
} | ||
get n() { | ||
return this._n; | ||
} | ||
get e() { | ||
return this._e; | ||
} | ||
get d() { | ||
return this._d; | ||
} | ||
} | ||
export default class RSAAESAuthenticationState extends EventTargetMixin { | ||
@@ -413,3 +146,3 @@ constructor(sock, getCredentials) { | ||
await this._waitSockAsync(4); | ||
const serverKeyLengthBuffer = this._sock.rQslice(0, 4); | ||
const serverKeyLengthBuffer = this._sock.rQpeekBytes(4); | ||
const serverKeyLength = this._sock.rQshift32(); | ||
@@ -425,4 +158,4 @@ if (serverKeyLength < 1024) { | ||
const serverE = this._sock.rQshiftBytes(serverKeyBytes); | ||
const serverRSACipher = new RSACipher(serverKeyLength); | ||
serverRSACipher.setPublicKey(serverN, serverE); | ||
const serverRSACipher = await legacyCrypto.importKey( | ||
"raw", { n: serverN, e: serverE }, { name: "RSA-PKCS1-v1_5" }, false, ["encrypt"]); | ||
const serverPublickey = new Uint8Array(4 + serverKeyBytes * 2); | ||
@@ -434,6 +167,7 @@ serverPublickey.set(serverKeyLengthBuffer); | ||
// verify server public key | ||
let approveKey = this._waitApproveKeyAsync(); | ||
this.dispatchEvent(new CustomEvent("serververification", { | ||
detail: { type: "RSA", publickey: serverPublickey } | ||
})); | ||
await this._waitApproveKeyAsync(); | ||
await approveKey; | ||
@@ -443,6 +177,10 @@ // 2: Send client public key | ||
const clientKeyBytes = Math.ceil(clientKeyLength / 8); | ||
const clientRSACipher = new RSACipher(clientKeyLength); | ||
await clientRSACipher.generateKey(); | ||
const clientN = clientRSACipher.n; | ||
const clientE = clientRSACipher.e; | ||
const clientRSACipher = (await legacyCrypto.generateKey({ | ||
name: "RSA-PKCS1-v1_5", | ||
modulusLength: clientKeyLength, | ||
publicExponent: new Uint8Array([1, 0, 1]), | ||
}, true, ["encrypt"])).privateKey; | ||
const clientExportedRSAKey = await legacyCrypto.exportKey("raw", clientRSACipher); | ||
const clientN = clientExportedRSAKey.n; | ||
const clientE = clientExportedRSAKey.e; | ||
const clientPublicKey = new Uint8Array(4 + clientKeyBytes * 2); | ||
@@ -455,3 +193,4 @@ clientPublicKey[0] = (clientKeyLength & 0xff000000) >>> 24; | ||
clientPublicKey.set(clientE, 4 + clientKeyBytes); | ||
this._sock.send(clientPublicKey); | ||
this._sock.sQpushBytes(clientPublicKey); | ||
this._sock.flush(); | ||
@@ -461,3 +200,4 @@ // 3: Send client random | ||
window.crypto.getRandomValues(clientRandom); | ||
const clientEncryptedRandom = serverRSACipher.encrypt(clientRandom); | ||
const clientEncryptedRandom = await legacyCrypto.encrypt( | ||
{ name: "RSA-PKCS1-v1_5" }, serverRSACipher, clientRandom); | ||
const clientRandomMessage = new Uint8Array(2 + serverKeyBytes); | ||
@@ -467,3 +207,4 @@ clientRandomMessage[0] = (serverKeyBytes & 0xff00) >>> 8; | ||
clientRandomMessage.set(clientEncryptedRandom, 2); | ||
this._sock.send(clientRandomMessage); | ||
this._sock.sQpushBytes(clientRandomMessage); | ||
this._sock.flush(); | ||
@@ -476,3 +217,4 @@ // 4: Receive server random | ||
const serverEncryptedRandom = this._sock.rQshiftBytes(clientKeyBytes); | ||
const serverRandom = clientRSACipher.decrypt(serverEncryptedRandom); | ||
const serverRandom = await legacyCrypto.decrypt( | ||
{ name: "RSA-PKCS1-v1_5" }, clientRSACipher, serverEncryptedRandom); | ||
if (serverRandom === null || serverRandom.length !== 16) { | ||
@@ -509,3 +251,4 @@ throw new Error("RA2: corrupted server encrypted random"); | ||
clientHash = new Uint8Array(clientHash); | ||
this._sock.send(await clientCipher.makeMessage(clientHash)); | ||
this._sock.sQpushBytes(await clientCipher.makeMessage(clientHash)); | ||
this._sock.flush(); | ||
await this._waitSockAsync(2 + 20 + 16); | ||
@@ -516,3 +259,3 @@ if (this._sock.rQshift16() !== 20) { | ||
const serverHashReceived = await serverCipher.receiveMessage( | ||
20, this._sock.rQshiftBytes(20), this._sock.rQshiftBytes(16)); | ||
20, this._sock.rQshiftBytes(20 + 16)); | ||
if (serverHashReceived === null) { | ||
@@ -533,3 +276,3 @@ throw new Error("RA2: failed to authenticate the message"); | ||
let subtype = (await serverCipher.receiveMessage( | ||
1, this._sock.rQshiftBytes(1), this._sock.rQshiftBytes(16))); | ||
1, this._sock.rQshiftBytes(1 + 16))); | ||
if (subtype === null) { | ||
@@ -539,2 +282,3 @@ throw new Error("RA2: failed to authenticate the message"); | ||
subtype = subtype[0]; | ||
let waitCredentials = this._waitCredentialsAsync(subtype); | ||
if (subtype === 1) { | ||
@@ -556,3 +300,3 @@ if (this._getCredentials().username === undefined || | ||
} | ||
await this._waitCredentialsAsync(subtype); | ||
await waitCredentials; | ||
let username; | ||
@@ -574,3 +318,4 @@ if (subtype === 1) { | ||
} | ||
this._sock.send(await clientCipher.makeMessage(credentials)); | ||
this._sock.sQpushBytes(await clientCipher.makeMessage(credentials)); | ||
this._sock.flush(); | ||
} | ||
@@ -585,2 +330,2 @@ | ||
} | ||
} | ||
} |
@@ -97,23 +97,3 @@ /* | ||
get sQ() { | ||
return this._sQ; | ||
} | ||
get rQ() { | ||
return this._rQ; | ||
} | ||
get rQi() { | ||
return this._rQi; | ||
} | ||
set rQi(val) { | ||
this._rQi = val; | ||
} | ||
// Receive Queue | ||
get rQlen() { | ||
return this._rQlen - this._rQi; | ||
} | ||
rQpeek8() { | ||
@@ -145,11 +125,10 @@ return this._rQ[this._rQi]; | ||
} | ||
return res; | ||
return res >>> 0; | ||
} | ||
rQshiftStr(len) { | ||
if (typeof(len) === 'undefined') { len = this.rQlen; } | ||
let str = ""; | ||
// Handle large arrays in steps to avoid long strings on the stack | ||
for (let i = 0; i < len; i += 4096) { | ||
let part = this.rQshiftBytes(Math.min(4096, len - i)); | ||
let part = this.rQshiftBytes(Math.min(4096, len - i), false); | ||
str += String.fromCharCode.apply(null, part); | ||
@@ -160,10 +139,12 @@ } | ||
rQshiftBytes(len) { | ||
if (typeof(len) === 'undefined') { len = this.rQlen; } | ||
rQshiftBytes(len, copy=true) { | ||
this._rQi += len; | ||
return new Uint8Array(this._rQ.buffer, this._rQi - len, len); | ||
if (copy) { | ||
return this._rQ.slice(this._rQi - len, this._rQi); | ||
} else { | ||
return this._rQ.subarray(this._rQi - len, this._rQi); | ||
} | ||
} | ||
rQshiftTo(target, len) { | ||
if (len === undefined) { len = this.rQlen; } | ||
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ | ||
@@ -174,4 +155,8 @@ target.set(new Uint8Array(this._rQ.buffer, this._rQi, len)); | ||
rQslice(start, end = this.rQlen) { | ||
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start); | ||
rQpeekBytes(len, copy=true) { | ||
if (copy) { | ||
return this._rQ.slice(this._rQi, this._rQi + len); | ||
} else { | ||
return this._rQ.subarray(this._rQi, this._rQi + len); | ||
} | ||
} | ||
@@ -183,3 +168,3 @@ | ||
rQwait(msg, num, goback) { | ||
if (this.rQlen < num) { | ||
if (this._rQlen - this._rQi < num) { | ||
if (goback) { | ||
@@ -198,5 +183,44 @@ if (this._rQi < goback) { | ||
sQpush8(num) { | ||
this._sQensureSpace(1); | ||
this._sQ[this._sQlen++] = num; | ||
} | ||
sQpush16(num) { | ||
this._sQensureSpace(2); | ||
this._sQ[this._sQlen++] = (num >> 8) & 0xff; | ||
this._sQ[this._sQlen++] = (num >> 0) & 0xff; | ||
} | ||
sQpush32(num) { | ||
this._sQensureSpace(4); | ||
this._sQ[this._sQlen++] = (num >> 24) & 0xff; | ||
this._sQ[this._sQlen++] = (num >> 16) & 0xff; | ||
this._sQ[this._sQlen++] = (num >> 8) & 0xff; | ||
this._sQ[this._sQlen++] = (num >> 0) & 0xff; | ||
} | ||
sQpushString(str) { | ||
let bytes = str.split('').map(chr => chr.charCodeAt(0)); | ||
this.sQpushBytes(new Uint8Array(bytes)); | ||
} | ||
sQpushBytes(bytes) { | ||
for (let offset = 0;offset < bytes.length;) { | ||
this._sQensureSpace(1); | ||
let chunkSize = this._sQbufferSize - this._sQlen; | ||
if (chunkSize > bytes.length - offset) { | ||
chunkSize = bytes.length - offset; | ||
} | ||
this._sQ.set(bytes.subarray(offset, chunkSize), this._sQlen); | ||
this._sQlen += chunkSize; | ||
offset += chunkSize; | ||
} | ||
} | ||
flush() { | ||
if (this._sQlen > 0 && this.readyState === 'open') { | ||
this._websocket.send(this._encodeMessage()); | ||
this._websocket.send(new Uint8Array(this._sQ.buffer, 0, this._sQlen)); | ||
this._sQlen = 0; | ||
@@ -206,12 +230,8 @@ } | ||
send(arr) { | ||
this._sQ.set(arr, this._sQlen); | ||
this._sQlen += arr.length; | ||
this.flush(); | ||
_sQensureSpace(bytes) { | ||
if (this._sQbufferSize - this._sQlen < bytes) { | ||
this.flush(); | ||
} | ||
} | ||
sendString(str) { | ||
this.send(str.split('').map(chr => chr.charCodeAt(0))); | ||
} | ||
// Event Handlers | ||
@@ -293,7 +313,2 @@ off(evt) { | ||
// private methods | ||
_encodeMessage() { | ||
// Put in a binary arraybuffer | ||
// according to the spec, you can send ArrayBufferViews with the send method | ||
return new Uint8Array(this._sQ.buffer, 0, this._sQlen); | ||
} | ||
@@ -304,3 +319,3 @@ // We want to move all the unread data to the start of the queue, | ||
// performance reasons we combine these two actions to avoid | ||
// unneccessary copying. | ||
// unnecessary copying. | ||
_expandCompactRQ(minFit) { | ||
@@ -321,3 +336,3 @@ // if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place | ||
this._rQbufferSize = MAX_RQ_GROW_SIZE; | ||
if (this._rQbufferSize - this.rQlen < minFit) { | ||
if (this._rQbufferSize - (this._rQlen - this._rQi) < minFit) { | ||
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); | ||
@@ -340,4 +355,10 @@ } | ||
// push arraybuffer values onto the end of the receive que | ||
_DecodeMessage(data) { | ||
const u8 = new Uint8Array(data); | ||
_recvMessage(e) { | ||
if (this._rQlen == this._rQi) { | ||
// All data has now been processed, this means we | ||
// can reset the receive queue. | ||
this._rQlen = 0; | ||
this._rQi = 0; | ||
} | ||
const u8 = new Uint8Array(e.data); | ||
if (u8.length > this._rQbufferSize - this._rQlen) { | ||
@@ -348,14 +369,5 @@ this._expandCompactRQ(u8.length); | ||
this._rQlen += u8.length; | ||
} | ||
_recvMessage(e) { | ||
this._DecodeMessage(e.data); | ||
if (this.rQlen > 0) { | ||
if (this._rQlen - this._rQi > 0) { | ||
this._eventHandlers.message(); | ||
if (this._rQlen == this._rQi) { | ||
// All data has now been processed, this means we | ||
// can reset the receive queue. | ||
this._rQlen = 0; | ||
this._rQi = 0; | ||
} | ||
} else { | ||
@@ -362,0 +374,0 @@ Log.Debug("Ignoring empty message"); |
@@ -15,3 +15,10 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
* | ||
*/ | ||
var HextileDecoder = /*#__PURE__*/function () { | ||
@@ -38,5 +45,3 @@ function HextileDecoder() { | ||
} | ||
var rQ = sock.rQ; | ||
var rQi = sock.rQi; | ||
var subencoding = rQ[rQi]; // Peek | ||
var subencoding = sock.rQpeek8(); | ||
if (subencoding > 30) { | ||
@@ -74,3 +79,3 @@ // Raw | ||
} | ||
var subrects = rQ[rQi + bytes - 1]; // Peek | ||
var subrects = sock.rQpeekBytes(bytes).at(-1); | ||
if (subencoding & 0x10) { | ||
@@ -89,3 +94,3 @@ // SubrectsColoured | ||
// We know the encoding and have a whole tile | ||
rQi++; | ||
sock.rQshift8(); | ||
if (subencoding === 0) { | ||
@@ -101,18 +106,16 @@ if (this._lastsubencoding & 0x01) { | ||
var pixels = tw * th; | ||
var data = sock.rQshiftBytes(pixels * 4, false); | ||
// Max sure the image is fully opaque | ||
for (var i = 0; i < pixels; i++) { | ||
rQ[rQi + i * 4 + 3] = 255; | ||
data[i * 4 + 3] = 255; | ||
} | ||
display.blitImage(tx, ty, tw, th, rQ, rQi); | ||
rQi += bytes - 1; | ||
display.blitImage(tx, ty, tw, th, data, 0); | ||
} else { | ||
if (subencoding & 0x02) { | ||
// Background | ||
this._background = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
this._background = new Uint8Array(sock.rQshiftBytes(4)); | ||
} | ||
if (subencoding & 0x04) { | ||
// Foreground | ||
this._foreground = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
this._foreground = new Uint8Array(sock.rQshiftBytes(4)); | ||
} | ||
@@ -122,4 +125,3 @@ this._startTile(tx, ty, tw, th, this._background); | ||
// AnySubrects | ||
var _subrects = rQ[rQi]; | ||
rQi++; | ||
var _subrects = sock.rQshift8(); | ||
for (var s = 0; s < _subrects; s++) { | ||
@@ -129,13 +131,10 @@ var color = void 0; | ||
// SubrectsColoured | ||
color = [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2], rQ[rQi + 3]]; | ||
rQi += 4; | ||
color = sock.rQshiftBytes(4); | ||
} else { | ||
color = this._foreground; | ||
} | ||
var xy = rQ[rQi]; | ||
rQi++; | ||
var xy = sock.rQshift8(); | ||
var sx = xy >> 4; | ||
var sy = xy & 0x0f; | ||
var wh = rQ[rQi]; | ||
rQi++; | ||
var wh = sock.rQshift8(); | ||
var sw = (wh >> 4) + 1; | ||
@@ -148,3 +147,2 @@ var sh = (wh & 0x0f) + 1; | ||
} | ||
sock.rQi = rQi; | ||
this._lastsubencoding = subencoding; | ||
@@ -151,0 +149,0 @@ this._tiles--; |
@@ -8,2 +8,9 @@ "use strict"; | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } | ||
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | ||
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } | ||
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } | ||
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } | ||
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } | ||
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -27,7 +34,4 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } | ||
// and Huffman tables, so we need to cache them. | ||
this._quantTables = []; | ||
this._huffmanTables = []; | ||
this._cachedQuantTables = []; | ||
this._cachedHuffmanTables = []; | ||
this._jpegLength = 0; | ||
this._segments = []; | ||
@@ -39,110 +43,134 @@ } | ||
// A rect of JPEG encodings is simply a JPEG file | ||
if (!this._parseJPEG(sock.rQslice(0))) { | ||
return false; | ||
while (true) { | ||
var segment = this._readSegment(sock); | ||
if (segment === null) { | ||
return false; | ||
} | ||
this._segments.push(segment); | ||
// End of image? | ||
if (segment[1] === 0xD9) { | ||
break; | ||
} | ||
} | ||
var data = sock.rQshiftBytes(this._jpegLength); | ||
if (this._quantTables.length != 0 && this._huffmanTables.length != 0) { | ||
// If there are quantization tables and Huffman tables in the JPEG | ||
// image, we can directly render it. | ||
display.imageRect(x, y, width, height, "image/jpeg", data); | ||
return true; | ||
} else { | ||
// Otherwise we need to insert cached tables. | ||
var sofIndex = this._segments.findIndex(function (x) { | ||
return x[1] == 0xC0 || x[1] == 0xC2; | ||
}); | ||
if (sofIndex == -1) { | ||
throw new Error("Illegal JPEG image without SOF"); | ||
var huffmanTables = []; | ||
var quantTables = []; | ||
var _iterator = _createForOfIteratorHelper(this._segments), | ||
_step; | ||
try { | ||
for (_iterator.s(); !(_step = _iterator.n()).done;) { | ||
var _segment = _step.value; | ||
var type = _segment[1]; | ||
if (type === 0xC4) { | ||
// Huffman tables | ||
huffmanTables.push(_segment); | ||
} else if (type === 0xDB) { | ||
// Quantization tables | ||
quantTables.push(_segment); | ||
} | ||
} | ||
var segments = this._segments.slice(0, sofIndex); | ||
segments = segments.concat(this._quantTables.length ? this._quantTables : this._cachedQuantTables); | ||
segments.push(this._segments[sofIndex]); | ||
segments = segments.concat(this._huffmanTables.length ? this._huffmanTables : this._cachedHuffmanTables, this._segments.slice(sofIndex + 1)); | ||
var length = 0; | ||
for (var i = 0; i < segments.length; i++) { | ||
length += segments[i].length; | ||
} catch (err) { | ||
_iterator.e(err); | ||
} finally { | ||
_iterator.f(); | ||
} | ||
var sofIndex = this._segments.findIndex(function (x) { | ||
return x[1] == 0xC0 || x[1] == 0xC2; | ||
}); | ||
if (sofIndex == -1) { | ||
throw new Error("Illegal JPEG image without SOF"); | ||
} | ||
if (quantTables.length === 0) { | ||
var _this$_segments; | ||
(_this$_segments = this._segments).splice.apply(_this$_segments, [sofIndex + 1, 0].concat(_toConsumableArray(this._cachedQuantTables))); | ||
} | ||
if (huffmanTables.length === 0) { | ||
var _this$_segments2; | ||
(_this$_segments2 = this._segments).splice.apply(_this$_segments2, [sofIndex + 1, 0].concat(_toConsumableArray(this._cachedHuffmanTables))); | ||
} | ||
var length = 0; | ||
var _iterator2 = _createForOfIteratorHelper(this._segments), | ||
_step2; | ||
try { | ||
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { | ||
var _segment2 = _step2.value; | ||
length += _segment2.length; | ||
} | ||
var _data = new Uint8Array(length); | ||
length = 0; | ||
for (var _i = 0; _i < segments.length; _i++) { | ||
_data.set(segments[_i], length); | ||
length += segments[_i].length; | ||
} catch (err) { | ||
_iterator2.e(err); | ||
} finally { | ||
_iterator2.f(); | ||
} | ||
var data = new Uint8Array(length); | ||
length = 0; | ||
var _iterator3 = _createForOfIteratorHelper(this._segments), | ||
_step3; | ||
try { | ||
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { | ||
var _segment3 = _step3.value; | ||
data.set(_segment3, length); | ||
length += _segment3.length; | ||
} | ||
display.imageRect(x, y, width, height, "image/jpeg", _data); | ||
return true; | ||
} catch (err) { | ||
_iterator3.e(err); | ||
} finally { | ||
_iterator3.f(); | ||
} | ||
display.imageRect(x, y, width, height, "image/jpeg", data); | ||
if (huffmanTables.length !== 0) { | ||
this._cachedHuffmanTables = huffmanTables; | ||
} | ||
if (quantTables.length !== 0) { | ||
this._cachedQuantTables = quantTables; | ||
} | ||
this._segments = []; | ||
return true; | ||
} | ||
}, { | ||
key: "_parseJPEG", | ||
value: function _parseJPEG(buffer) { | ||
if (this._quantTables.length != 0) { | ||
this._cachedQuantTables = this._quantTables; | ||
key: "_readSegment", | ||
value: function _readSegment(sock) { | ||
if (sock.rQwait("JPEG", 2)) { | ||
return null; | ||
} | ||
if (this._huffmanTables.length != 0) { | ||
this._cachedHuffmanTables = this._huffmanTables; | ||
var marker = sock.rQshift8(); | ||
if (marker != 0xFF) { | ||
throw new Error("Illegal JPEG marker received (byte: " + marker + ")"); | ||
} | ||
this._quantTables = []; | ||
this._huffmanTables = []; | ||
this._segments = []; | ||
var i = 0; | ||
var bufferLength = buffer.length; | ||
while (true) { | ||
var j = i; | ||
if (j + 2 > bufferLength) { | ||
return false; | ||
} | ||
if (buffer[j] != 0xFF) { | ||
throw new Error("Illegal JPEG marker received (byte: " + buffer[j] + ")"); | ||
} | ||
var type = buffer[j + 1]; | ||
j += 2; | ||
if (type == 0xD9) { | ||
this._jpegLength = j; | ||
this._segments.push(buffer.slice(i, j)); | ||
return true; | ||
} else if (type == 0xDA) { | ||
// start of scan | ||
var hasFoundEndOfScan = false; | ||
for (var k = j + 3; k + 1 < bufferLength; k++) { | ||
if (buffer[k] == 0xFF && buffer[k + 1] != 0x00 && !(buffer[k + 1] >= 0xD0 && buffer[k + 1] <= 0xD7)) { | ||
j = k; | ||
hasFoundEndOfScan = true; | ||
break; | ||
} | ||
var type = sock.rQshift8(); | ||
if (type >= 0xD0 && type <= 0xD9 || type == 0x01) { | ||
// No length after marker | ||
return new Uint8Array([marker, type]); | ||
} | ||
if (sock.rQwait("JPEG", 2, 2)) { | ||
return null; | ||
} | ||
var length = sock.rQshift16(); | ||
if (length < 2) { | ||
throw new Error("Illegal JPEG length received (length: " + length + ")"); | ||
} | ||
if (sock.rQwait("JPEG", length - 2, 4)) { | ||
return null; | ||
} | ||
var extra = 0; | ||
if (type === 0xDA) { | ||
// start of scan | ||
extra += 2; | ||
while (true) { | ||
if (sock.rQwait("JPEG", length - 2 + extra, 4)) { | ||
return null; | ||
} | ||
if (!hasFoundEndOfScan) { | ||
return false; | ||
var data = sock.rQpeekBytes(length - 2 + extra, false); | ||
if (data.at(-2) === 0xFF && data.at(-1) !== 0x00 && !(data.at(-1) >= 0xD0 && data.at(-1) <= 0xD7)) { | ||
extra -= 2; | ||
break; | ||
} | ||
this._segments.push(buffer.slice(i, j)); | ||
i = j; | ||
continue; | ||
} else if (type >= 0xD0 && type < 0xD9 || type == 0x01) { | ||
// No length after marker | ||
this._segments.push(buffer.slice(i, j)); | ||
i = j; | ||
continue; | ||
extra++; | ||
} | ||
if (j + 2 > bufferLength) { | ||
return false; | ||
} | ||
var length = (buffer[j] << 8) + buffer[j + 1] - 2; | ||
if (length < 0) { | ||
throw new Error("Illegal JPEG length received (length: " + length + ")"); | ||
} | ||
j += 2; | ||
if (j + length > bufferLength) { | ||
return false; | ||
} | ||
j += length; | ||
var segment = buffer.slice(i, j); | ||
if (type == 0xC4) { | ||
// Huffman tables | ||
this._huffmanTables.push(segment); | ||
} else if (type == 0xDB) { | ||
// Quantization tables | ||
this._quantTables.push(segment); | ||
} | ||
this._segments.push(segment); | ||
i = j; | ||
} | ||
var segment = new Uint8Array(2 + length + extra); | ||
segment[0] = marker; | ||
segment[1] = type; | ||
segment[2] = length >> 8; | ||
segment[3] = length; | ||
segment.set(sock.rQshiftBytes(length - 2 + extra, false), 4); | ||
return segment; | ||
} | ||
@@ -149,0 +177,0 @@ }]); |
@@ -37,34 +37,28 @@ "use strict"; | ||
var bytesPerLine = width * pixelSize; | ||
if (sock.rQwait("RAW", bytesPerLine)) { | ||
return false; | ||
} | ||
var curY = y + (height - this._lines); | ||
var currHeight = Math.min(this._lines, Math.floor(sock.rQlen / bytesPerLine)); | ||
var pixels = width * currHeight; | ||
var data = sock.rQ; | ||
var index = sock.rQi; | ||
while (this._lines > 0) { | ||
if (sock.rQwait("RAW", bytesPerLine)) { | ||
return false; | ||
} | ||
var curY = y + (height - this._lines); | ||
var data = sock.rQshiftBytes(bytesPerLine, false); | ||
// Convert data if needed | ||
if (depth == 8) { | ||
var newdata = new Uint8Array(pixels * 4); | ||
for (var i = 0; i < pixels; i++) { | ||
newdata[i * 4 + 0] = (data[index + i] >> 0 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 1] = (data[index + i] >> 2 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 2] = (data[index + i] >> 4 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 3] = 255; | ||
// Convert data if needed | ||
if (depth == 8) { | ||
var newdata = new Uint8Array(width * 4); | ||
for (var i = 0; i < width; i++) { | ||
newdata[i * 4 + 0] = (data[i] >> 0 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 1] = (data[i] >> 2 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 2] = (data[i] >> 4 & 0x3) * 255 / 3; | ||
newdata[i * 4 + 3] = 255; | ||
} | ||
data = newdata; | ||
} | ||
data = newdata; | ||
index = 0; | ||
} | ||
// Max sure the image is fully opaque | ||
for (var _i = 0; _i < pixels; _i++) { | ||
data[index + _i * 4 + 3] = 255; | ||
// Max sure the image is fully opaque | ||
for (var _i = 0; _i < width; _i++) { | ||
data[_i * 4 + 3] = 255; | ||
} | ||
display.blitImage(x, curY, width, 1, data, 0); | ||
this._lines--; | ||
} | ||
display.blitImage(x, curY, width, currHeight, data, index); | ||
sock.rQskipBytes(currHeight * bytesPerLine); | ||
this._lines -= currHeight; | ||
if (this._lines > 0) { | ||
return false; | ||
} | ||
return true; | ||
@@ -71,0 +65,0 @@ } |
@@ -17,3 +17,11 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
* | ||
*/ | ||
var TightDecoder = /*#__PURE__*/function () { | ||
@@ -75,6 +83,4 @@ function TightDecoder() { | ||
} | ||
var rQi = sock.rQi; | ||
var rQ = sock.rQ; | ||
display.fillRect(x, y, width, height, [rQ[rQi], rQ[rQi + 1], rQ[rQi + 2]], false); | ||
sock.rQskipBytes(3); | ||
var pixel = sock.rQshiftBytes(3); | ||
display.fillRect(x, y, width, height, pixel, false); | ||
return true; | ||
@@ -289,3 +295,3 @@ } | ||
} | ||
var data = sock.rQshiftBytes(this._len); | ||
var data = sock.rQshiftBytes(this._len, false); | ||
this._len = 0; | ||
@@ -292,0 +298,0 @@ return data; |
@@ -21,3 +21,10 @@ "use strict"; | ||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } | ||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } | ||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
* | ||
*/ | ||
var TightPNGDecoder = /*#__PURE__*/function (_TightDecoder) { | ||
@@ -24,0 +31,0 @@ _inherits(TightPNGDecoder, _TightDecoder); |
@@ -14,3 +14,10 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2021 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
* | ||
*/ | ||
var ZRLE_TILE_WIDTH = 64; | ||
@@ -38,3 +45,3 @@ var ZRLE_TILE_HEIGHT = 64; | ||
} | ||
var data = sock.rQshiftBytes(this._length); | ||
var data = sock.rQshiftBytes(this._length, false); | ||
this._inflator.setInput(data); | ||
@@ -41,0 +48,0 @@ for (var ty = y; ty < y + height; ty += ZRLE_TILE_HEIGHT) { |
@@ -15,3 +15,9 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2020 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
*/ | ||
var Deflator = /*#__PURE__*/function () { | ||
@@ -18,0 +24,0 @@ function Deflator() { |
@@ -18,3 +18,9 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
*/ | ||
var Display = /*#__PURE__*/function () { | ||
@@ -25,3 +31,3 @@ function Display(target) { | ||
this._renderQ = []; // queue drawing actions for in-oder rendering | ||
this._flushing = false; | ||
this._flushPromise = null; | ||
@@ -71,6 +77,2 @@ // the full frame buffer (logical canvas) size | ||
this._clipViewport = false; | ||
// ===== EVENT HANDLERS ===== | ||
this.onflush = function () {}; // A flush request has finished | ||
} | ||
@@ -310,6 +312,12 @@ | ||
value: function flush() { | ||
var _this = this; | ||
if (this._renderQ.length === 0) { | ||
this.onflush(); | ||
return Promise.resolve(); | ||
} else { | ||
this._flushing = true; | ||
if (this._flushPromise === null) { | ||
this._flushPromise = new Promise(function (resolve) { | ||
_this._flushResolve = resolve; | ||
}); | ||
} | ||
return this._flushPromise; | ||
} | ||
@@ -516,5 +524,6 @@ } | ||
} | ||
if (this._renderQ.length === 0 && this._flushing) { | ||
this._flushing = false; | ||
this.onflush(); | ||
if (this._renderQ.length === 0 && this._flushPromise !== null) { | ||
this._flushResolve(); | ||
this._flushPromise = null; | ||
this._flushResolve = null; | ||
} | ||
@@ -521,0 +530,0 @@ } |
@@ -15,3 +15,9 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2020 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* See README.md for usage and integration instructions. | ||
*/ | ||
var Inflate = /*#__PURE__*/function () { | ||
@@ -18,0 +24,0 @@ function Inflate() { |
@@ -20,3 +20,7 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||
*/ | ||
// | ||
@@ -23,0 +27,0 @@ // Keyboard event handler |
816
lib/ra2.js
@@ -6,8 +6,7 @@ "use strict"; | ||
}); | ||
exports["default"] = exports.RSACipher = exports.RA2Cipher = exports.AESEAXCipher = void 0; | ||
var _base = _interopRequireDefault(require("./base64.js")); | ||
exports["default"] = void 0; | ||
var _strings = require("./util/strings.js"); | ||
var _eventtarget = _interopRequireDefault(require("./util/eventtarget.js")); | ||
var _crypto = _interopRequireDefault(require("./crypto/crypto.js")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } | ||
@@ -20,2 +19,3 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } | ||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } | ||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } | ||
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, defineProperty = Object.defineProperty || function (obj, key, desc) { obj[key] = desc.value; }, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return defineProperty(generator, "_invoke", { value: makeInvokeMethod(innerFn, self, context) }), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; defineProperty(this, "_invoke", { value: function value(method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; } function maybeInvokeDelegate(delegate, context) { var methodName = context.method, method = delegate.iterator[methodName]; if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel; var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), defineProperty(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (val) { var object = Object(val), keys = []; for (var key in object) keys.push(key); return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; } | ||
@@ -29,18 +29,12 @@ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
var AESEAXCipher = /*#__PURE__*/function () { | ||
function AESEAXCipher() { | ||
_classCallCheck(this, AESEAXCipher); | ||
this._rawKey = null; | ||
this._ctrKey = null; | ||
this._cbcKey = null; | ||
this._zeroBlock = new Uint8Array(16); | ||
this._prefixBlock0 = this._zeroBlock; | ||
this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); | ||
this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); | ||
var RA2Cipher = /*#__PURE__*/function () { | ||
function RA2Cipher() { | ||
_classCallCheck(this, RA2Cipher); | ||
this._cipher = null; | ||
this._counter = new Uint8Array(16); | ||
} | ||
_createClass(AESEAXCipher, [{ | ||
key: "_encryptBlock", | ||
_createClass(RA2Cipher, [{ | ||
key: "setKey", | ||
value: function () { | ||
var _encryptBlock2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(block) { | ||
var encrypted; | ||
var _setKey = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(key) { | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
@@ -50,10 +44,8 @@ while (1) switch (_context.prev = _context.next) { | ||
_context.next = 2; | ||
return window.crypto.subtle.encrypt({ | ||
name: "AES-CBC", | ||
iv: this._zeroBlock | ||
}, this._cbcKey, block); | ||
return _crypto["default"].importKey("raw", key, { | ||
name: "AES-EAX" | ||
}, false, ["encrypt, decrypt"]); | ||
case 2: | ||
encrypted = _context.sent; | ||
return _context.abrupt("return", new Uint8Array(encrypted).slice(0, 16)); | ||
case 4: | ||
this._cipher = _context.sent; | ||
case 3: | ||
case "end": | ||
@@ -64,178 +56,3 @@ return _context.stop(); | ||
})); | ||
function _encryptBlock(_x) { | ||
return _encryptBlock2.apply(this, arguments); | ||
} | ||
return _encryptBlock; | ||
}() | ||
}, { | ||
key: "_initCMAC", | ||
value: function () { | ||
var _initCMAC2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { | ||
var k1, k2, v, i, lut; | ||
return _regeneratorRuntime().wrap(function _callee2$(_context2) { | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
_context2.next = 2; | ||
return this._encryptBlock(this._zeroBlock); | ||
case 2: | ||
k1 = _context2.sent; | ||
k2 = new Uint8Array(16); | ||
v = k1[0] >>> 6; | ||
for (i = 0; i < 15; i++) { | ||
k2[i] = k1[i + 1] >> 6 | k1[i] << 2; | ||
k1[i] = k1[i + 1] >> 7 | k1[i] << 1; | ||
} | ||
lut = [0x0, 0x87, 0x0e, 0x89]; | ||
k2[14] ^= v >>> 1; | ||
k2[15] = k1[15] << 2 ^ lut[v]; | ||
k1[15] = k1[15] << 1 ^ lut[v >> 1]; | ||
this._k1 = k1; | ||
this._k2 = k2; | ||
case 12: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
}, _callee2, this); | ||
})); | ||
function _initCMAC() { | ||
return _initCMAC2.apply(this, arguments); | ||
} | ||
return _initCMAC; | ||
}() | ||
}, { | ||
key: "_encryptCTR", | ||
value: function () { | ||
var _encryptCTR2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(data, counter) { | ||
var encrypted; | ||
return _regeneratorRuntime().wrap(function _callee3$(_context3) { | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
_context3.next = 2; | ||
return window.crypto.subtle.encrypt({ | ||
"name": "AES-CTR", | ||
counter: counter, | ||
length: 128 | ||
}, this._ctrKey, data); | ||
case 2: | ||
encrypted = _context3.sent; | ||
return _context3.abrupt("return", new Uint8Array(encrypted)); | ||
case 4: | ||
case "end": | ||
return _context3.stop(); | ||
} | ||
}, _callee3, this); | ||
})); | ||
function _encryptCTR(_x2, _x3) { | ||
return _encryptCTR2.apply(this, arguments); | ||
} | ||
return _encryptCTR; | ||
}() | ||
}, { | ||
key: "_decryptCTR", | ||
value: function () { | ||
var _decryptCTR2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(data, counter) { | ||
var decrypted; | ||
return _regeneratorRuntime().wrap(function _callee4$(_context4) { | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context4.next = 2; | ||
return window.crypto.subtle.decrypt({ | ||
"name": "AES-CTR", | ||
counter: counter, | ||
length: 128 | ||
}, this._ctrKey, data); | ||
case 2: | ||
decrypted = _context4.sent; | ||
return _context4.abrupt("return", new Uint8Array(decrypted)); | ||
case 4: | ||
case "end": | ||
return _context4.stop(); | ||
} | ||
}, _callee4, this); | ||
})); | ||
function _decryptCTR(_x4, _x5) { | ||
return _decryptCTR2.apply(this, arguments); | ||
} | ||
return _decryptCTR; | ||
}() | ||
}, { | ||
key: "_computeCMAC", | ||
value: function () { | ||
var _computeCMAC2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(data, prefixBlock) { | ||
var n, m, r, cbcData, i, _i, cbcEncrypted, mac; | ||
return _regeneratorRuntime().wrap(function _callee5$(_context5) { | ||
while (1) switch (_context5.prev = _context5.next) { | ||
case 0: | ||
if (!(prefixBlock.length !== 16)) { | ||
_context5.next = 2; | ||
break; | ||
} | ||
return _context5.abrupt("return", null); | ||
case 2: | ||
n = Math.floor(data.length / 16); | ||
m = Math.ceil(data.length / 16); | ||
r = data.length - n * 16; | ||
cbcData = new Uint8Array((m + 1) * 16); | ||
cbcData.set(prefixBlock); | ||
cbcData.set(data, 16); | ||
if (r === 0) { | ||
for (i = 0; i < 16; i++) { | ||
cbcData[n * 16 + i] ^= this._k1[i]; | ||
} | ||
} else { | ||
cbcData[(n + 1) * 16 + r] = 0x80; | ||
for (_i = 0; _i < 16; _i++) { | ||
cbcData[(n + 1) * 16 + _i] ^= this._k2[_i]; | ||
} | ||
} | ||
_context5.next = 11; | ||
return window.crypto.subtle.encrypt({ | ||
name: "AES-CBC", | ||
iv: this._zeroBlock | ||
}, this._cbcKey, cbcData); | ||
case 11: | ||
cbcEncrypted = _context5.sent; | ||
cbcEncrypted = new Uint8Array(cbcEncrypted); | ||
mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16); | ||
return _context5.abrupt("return", mac); | ||
case 15: | ||
case "end": | ||
return _context5.stop(); | ||
} | ||
}, _callee5, this); | ||
})); | ||
function _computeCMAC(_x6, _x7) { | ||
return _computeCMAC2.apply(this, arguments); | ||
} | ||
return _computeCMAC; | ||
}() | ||
}, { | ||
key: "setKey", | ||
value: function () { | ||
var _setKey = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(key) { | ||
return _regeneratorRuntime().wrap(function _callee6$(_context6) { | ||
while (1) switch (_context6.prev = _context6.next) { | ||
case 0: | ||
this._rawKey = key; | ||
_context6.next = 3; | ||
return window.crypto.subtle.importKey("raw", key, { | ||
"name": "AES-CTR" | ||
}, false, ["encrypt", "decrypt"]); | ||
case 3: | ||
this._ctrKey = _context6.sent; | ||
_context6.next = 6; | ||
return window.crypto.subtle.importKey("raw", key, { | ||
"name": "AES-CBC" | ||
}, false, ["encrypt", "decrypt"]); | ||
case 6: | ||
this._cbcKey = _context6.sent; | ||
_context6.next = 9; | ||
return this._initCMAC(); | ||
case 9: | ||
case "end": | ||
return _context6.stop(); | ||
} | ||
}, _callee6, this); | ||
})); | ||
function setKey(_x8) { | ||
function setKey(_x) { | ||
return _setKey.apply(this, arguments); | ||
@@ -246,147 +63,18 @@ } | ||
}, { | ||
key: "encrypt", | ||
value: function () { | ||
var _encrypt = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(message, associatedData, nonce) { | ||
var nCMAC, encrypted, adCMAC, mac, i, res; | ||
return _regeneratorRuntime().wrap(function _callee7$(_context7) { | ||
while (1) switch (_context7.prev = _context7.next) { | ||
case 0: | ||
_context7.next = 2; | ||
return this._computeCMAC(nonce, this._prefixBlock0); | ||
case 2: | ||
nCMAC = _context7.sent; | ||
_context7.next = 5; | ||
return this._encryptCTR(message, nCMAC); | ||
case 5: | ||
encrypted = _context7.sent; | ||
_context7.next = 8; | ||
return this._computeCMAC(associatedData, this._prefixBlock1); | ||
case 8: | ||
adCMAC = _context7.sent; | ||
_context7.next = 11; | ||
return this._computeCMAC(encrypted, this._prefixBlock2); | ||
case 11: | ||
mac = _context7.sent; | ||
for (i = 0; i < 16; i++) { | ||
mac[i] ^= nCMAC[i] ^ adCMAC[i]; | ||
} | ||
res = new Uint8Array(16 + encrypted.length); | ||
res.set(encrypted); | ||
res.set(mac, encrypted.length); | ||
return _context7.abrupt("return", res); | ||
case 17: | ||
case "end": | ||
return _context7.stop(); | ||
} | ||
}, _callee7, this); | ||
})); | ||
function encrypt(_x9, _x10, _x11) { | ||
return _encrypt.apply(this, arguments); | ||
} | ||
return encrypt; | ||
}() | ||
}, { | ||
key: "decrypt", | ||
value: function () { | ||
var _decrypt = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(encrypted, associatedData, nonce, mac) { | ||
var nCMAC, adCMAC, computedMac, i, _i2, res; | ||
return _regeneratorRuntime().wrap(function _callee8$(_context8) { | ||
while (1) switch (_context8.prev = _context8.next) { | ||
case 0: | ||
_context8.next = 2; | ||
return this._computeCMAC(nonce, this._prefixBlock0); | ||
case 2: | ||
nCMAC = _context8.sent; | ||
_context8.next = 5; | ||
return this._computeCMAC(associatedData, this._prefixBlock1); | ||
case 5: | ||
adCMAC = _context8.sent; | ||
_context8.next = 8; | ||
return this._computeCMAC(encrypted, this._prefixBlock2); | ||
case 8: | ||
computedMac = _context8.sent; | ||
for (i = 0; i < 16; i++) { | ||
computedMac[i] ^= nCMAC[i] ^ adCMAC[i]; | ||
} | ||
if (!(computedMac.length !== mac.length)) { | ||
_context8.next = 12; | ||
break; | ||
} | ||
return _context8.abrupt("return", null); | ||
case 12: | ||
_i2 = 0; | ||
case 13: | ||
if (!(_i2 < mac.length)) { | ||
_context8.next = 19; | ||
break; | ||
} | ||
if (!(computedMac[_i2] !== mac[_i2])) { | ||
_context8.next = 16; | ||
break; | ||
} | ||
return _context8.abrupt("return", null); | ||
case 16: | ||
_i2++; | ||
_context8.next = 13; | ||
break; | ||
case 19: | ||
_context8.next = 21; | ||
return this._decryptCTR(encrypted, nCMAC); | ||
case 21: | ||
res = _context8.sent; | ||
return _context8.abrupt("return", res); | ||
case 23: | ||
case "end": | ||
return _context8.stop(); | ||
} | ||
}, _callee8, this); | ||
})); | ||
function decrypt(_x12, _x13, _x14, _x15) { | ||
return _decrypt.apply(this, arguments); | ||
} | ||
return decrypt; | ||
}() | ||
}]); | ||
return AESEAXCipher; | ||
}(); | ||
exports.AESEAXCipher = AESEAXCipher; | ||
var RA2Cipher = /*#__PURE__*/function () { | ||
function RA2Cipher() { | ||
_classCallCheck(this, RA2Cipher); | ||
this._cipher = new AESEAXCipher(); | ||
this._counter = new Uint8Array(16); | ||
} | ||
_createClass(RA2Cipher, [{ | ||
key: "setKey", | ||
value: function () { | ||
var _setKey2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(key) { | ||
return _regeneratorRuntime().wrap(function _callee9$(_context9) { | ||
while (1) switch (_context9.prev = _context9.next) { | ||
case 0: | ||
_context9.next = 2; | ||
return this._cipher.setKey(key); | ||
case 2: | ||
case "end": | ||
return _context9.stop(); | ||
} | ||
}, _callee9, this); | ||
})); | ||
function setKey(_x16) { | ||
return _setKey2.apply(this, arguments); | ||
} | ||
return setKey; | ||
}() | ||
}, { | ||
key: "makeMessage", | ||
value: function () { | ||
var _makeMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(message) { | ||
var _makeMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(message) { | ||
var ad, encrypted, i, res; | ||
return _regeneratorRuntime().wrap(function _callee10$(_context10) { | ||
while (1) switch (_context10.prev = _context10.next) { | ||
return _regeneratorRuntime().wrap(function _callee2$(_context2) { | ||
while (1) switch (_context2.prev = _context2.next) { | ||
case 0: | ||
ad = new Uint8Array([(message.length & 0xff00) >>> 8, message.length & 0xff]); | ||
_context10.next = 3; | ||
return this._cipher.encrypt(message, ad, this._counter); | ||
_context2.next = 3; | ||
return _crypto["default"].encrypt({ | ||
name: "AES-EAX", | ||
iv: this._counter, | ||
additionalData: ad | ||
}, this._cipher, message); | ||
case 3: | ||
encrypted = _context10.sent; | ||
encrypted = _context2.sent; | ||
for (i = 0; i < 16 && this._counter[i]++ === 255; i++); | ||
@@ -396,10 +84,10 @@ res = new Uint8Array(message.length + 2 + 16); | ||
res.set(encrypted, 2); | ||
return _context10.abrupt("return", res); | ||
return _context2.abrupt("return", res); | ||
case 9: | ||
case "end": | ||
return _context10.stop(); | ||
return _context2.stop(); | ||
} | ||
}, _callee10, this); | ||
}, _callee2, this); | ||
})); | ||
function makeMessage(_x17) { | ||
function makeMessage(_x2) { | ||
return _makeMessage.apply(this, arguments); | ||
@@ -412,21 +100,25 @@ } | ||
value: function () { | ||
var _receiveMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(length, encrypted, mac) { | ||
var _receiveMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(length, encrypted) { | ||
var ad, res, i; | ||
return _regeneratorRuntime().wrap(function _callee11$(_context11) { | ||
while (1) switch (_context11.prev = _context11.next) { | ||
return _regeneratorRuntime().wrap(function _callee3$(_context3) { | ||
while (1) switch (_context3.prev = _context3.next) { | ||
case 0: | ||
ad = new Uint8Array([(length & 0xff00) >>> 8, length & 0xff]); | ||
_context11.next = 3; | ||
return this._cipher.decrypt(encrypted, ad, this._counter, mac); | ||
_context3.next = 3; | ||
return _crypto["default"].decrypt({ | ||
name: "AES-EAX", | ||
iv: this._counter, | ||
additionalData: ad | ||
}, this._cipher, encrypted); | ||
case 3: | ||
res = _context11.sent; | ||
res = _context3.sent; | ||
for (i = 0; i < 16 && this._counter[i]++ === 255; i++); | ||
return _context11.abrupt("return", res); | ||
return _context3.abrupt("return", res); | ||
case 6: | ||
case "end": | ||
return _context11.stop(); | ||
return _context3.stop(); | ||
} | ||
}, _callee11, this); | ||
}, _callee3, this); | ||
})); | ||
function receiveMessage(_x18, _x19, _x20) { | ||
function receiveMessage(_x3, _x4) { | ||
return _receiveMessage.apply(this, arguments); | ||
@@ -439,191 +131,2 @@ } | ||
}(); | ||
exports.RA2Cipher = RA2Cipher; | ||
var RSACipher = /*#__PURE__*/function () { | ||
function RSACipher(keyLength) { | ||
_classCallCheck(this, RSACipher); | ||
this._key = null; | ||
this._keyLength = keyLength; | ||
this._keyBytes = Math.ceil(keyLength / 8); | ||
this._n = null; | ||
this._e = null; | ||
this._d = null; | ||
this._nBigInt = null; | ||
this._eBigInt = null; | ||
this._dBigInt = null; | ||
} | ||
_createClass(RSACipher, [{ | ||
key: "_base64urlDecode", | ||
value: function _base64urlDecode(data) { | ||
data = data.replace(/-/g, "+").replace(/_/g, "/"); | ||
data = data.padEnd(Math.ceil(data.length / 4) * 4, "="); | ||
return _base["default"].decode(data); | ||
} | ||
}, { | ||
key: "_u8ArrayToBigInt", | ||
value: function _u8ArrayToBigInt(arr) { | ||
var hex = '0x'; | ||
for (var i = 0; i < arr.length; i++) { | ||
hex += arr[i].toString(16).padStart(2, '0'); | ||
} | ||
return BigInt(hex); | ||
} | ||
}, { | ||
key: "_padArray", | ||
value: function _padArray(arr, length) { | ||
var res = new Uint8Array(length); | ||
res.set(arr, length - arr.length); | ||
return res; | ||
} | ||
}, { | ||
key: "_bigIntToU8Array", | ||
value: function _bigIntToU8Array(bigint) { | ||
var padLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
var hex = bigint.toString(16); | ||
if (padLength === 0) { | ||
padLength = Math.ceil(hex.length / 2) * 2; | ||
} | ||
hex = hex.padStart(padLength * 2, '0'); | ||
var length = hex.length / 2; | ||
var arr = new Uint8Array(length); | ||
for (var i = 0; i < length; i++) { | ||
arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); | ||
} | ||
return arr; | ||
} | ||
}, { | ||
key: "_modPow", | ||
value: function _modPow(b, e, m) { | ||
if (m === 1n) { | ||
return 0; | ||
} | ||
var r = 1n; | ||
b = b % m; | ||
while (e > 0) { | ||
if (e % 2n === 1n) { | ||
r = r * b % m; | ||
} | ||
e = e / 2n; | ||
b = b * b % m; | ||
} | ||
return r; | ||
} | ||
}, { | ||
key: "generateKey", | ||
value: function () { | ||
var _generateKey = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12() { | ||
var privateKey; | ||
return _regeneratorRuntime().wrap(function _callee12$(_context12) { | ||
while (1) switch (_context12.prev = _context12.next) { | ||
case 0: | ||
_context12.next = 2; | ||
return window.crypto.subtle.generateKey({ | ||
name: "RSA-OAEP", | ||
modulusLength: this._keyLength, | ||
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), | ||
hash: { | ||
name: "SHA-256" | ||
} | ||
}, true, ["encrypt", "decrypt"]); | ||
case 2: | ||
this._key = _context12.sent; | ||
_context12.next = 5; | ||
return window.crypto.subtle.exportKey("jwk", this._key.privateKey); | ||
case 5: | ||
privateKey = _context12.sent; | ||
this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes); | ||
this._nBigInt = this._u8ArrayToBigInt(this._n); | ||
this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes); | ||
this._eBigInt = this._u8ArrayToBigInt(this._e); | ||
this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes); | ||
this._dBigInt = this._u8ArrayToBigInt(this._d); | ||
case 12: | ||
case "end": | ||
return _context12.stop(); | ||
} | ||
}, _callee12, this); | ||
})); | ||
function generateKey() { | ||
return _generateKey.apply(this, arguments); | ||
} | ||
return generateKey; | ||
}() | ||
}, { | ||
key: "setPublicKey", | ||
value: function setPublicKey(n, e) { | ||
if (n.length !== this._keyBytes || e.length !== this._keyBytes) { | ||
return; | ||
} | ||
this._n = new Uint8Array(this._keyBytes); | ||
this._e = new Uint8Array(this._keyBytes); | ||
this._n.set(n); | ||
this._e.set(e); | ||
this._nBigInt = this._u8ArrayToBigInt(this._n); | ||
this._eBigInt = this._u8ArrayToBigInt(this._e); | ||
} | ||
}, { | ||
key: "encrypt", | ||
value: function encrypt(message) { | ||
if (message.length > this._keyBytes - 11) { | ||
return null; | ||
} | ||
var ps = new Uint8Array(this._keyBytes - message.length - 3); | ||
window.crypto.getRandomValues(ps); | ||
for (var i = 0; i < ps.length; i++) { | ||
ps[i] = Math.floor(ps[i] * 254 / 255 + 1); | ||
} | ||
var em = new Uint8Array(this._keyBytes); | ||
em[1] = 0x02; | ||
em.set(ps, 2); | ||
em.set(message, ps.length + 3); | ||
var emBigInt = this._u8ArrayToBigInt(em); | ||
var c = this._modPow(emBigInt, this._eBigInt, this._nBigInt); | ||
return this._bigIntToU8Array(c, this._keyBytes); | ||
} | ||
}, { | ||
key: "decrypt", | ||
value: function decrypt(message) { | ||
if (message.length !== this._keyBytes) { | ||
return null; | ||
} | ||
var msgBigInt = this._u8ArrayToBigInt(message); | ||
var emBigInt = this._modPow(msgBigInt, this._dBigInt, this._nBigInt); | ||
var em = this._bigIntToU8Array(emBigInt, this._keyBytes); | ||
if (em[0] !== 0x00 || em[1] !== 0x02) { | ||
return null; | ||
} | ||
var i = 2; | ||
for (; i < em.length; i++) { | ||
if (em[i] === 0x00) { | ||
break; | ||
} | ||
} | ||
if (i === em.length) { | ||
return null; | ||
} | ||
return em.slice(i + 1, em.length); | ||
} | ||
}, { | ||
key: "keyLength", | ||
get: function get() { | ||
return this._keyLength; | ||
} | ||
}, { | ||
key: "n", | ||
get: function get() { | ||
return this._n; | ||
} | ||
}, { | ||
key: "e", | ||
get: function get() { | ||
return this._e; | ||
} | ||
}, { | ||
key: "d", | ||
get: function get() { | ||
return this._d; | ||
} | ||
}]); | ||
return RSACipher; | ||
}(); | ||
exports.RSACipher = RSACipher; | ||
var RSAAESAuthenticationState = /*#__PURE__*/function (_EventTargetMixin) { | ||
@@ -742,16 +245,16 @@ _inherits(RSAAESAuthenticationState, _EventTargetMixin); | ||
value: function () { | ||
var _negotiateRA2neAuthAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee13() { | ||
var serverKeyLengthBuffer, serverKeyLength, serverKeyBytes, serverN, serverE, serverRSACipher, serverPublickey, clientKeyLength, clientKeyBytes, clientRSACipher, clientN, clientE, clientPublicKey, clientRandom, clientEncryptedRandom, clientRandomMessage, serverEncryptedRandom, serverRandom, clientSessionKey, serverSessionKey, clientCipher, serverCipher, serverHash, clientHash, serverHashReceived, i, subtype, username, password, credentials, _i3, _i4; | ||
return _regeneratorRuntime().wrap(function _callee13$(_context13) { | ||
while (1) switch (_context13.prev = _context13.next) { | ||
var _negotiateRA2neAuthAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { | ||
var serverKeyLengthBuffer, serverKeyLength, serverKeyBytes, serverN, serverE, serverRSACipher, serverPublickey, approveKey, clientKeyLength, clientKeyBytes, clientRSACipher, clientExportedRSAKey, clientN, clientE, clientPublicKey, clientRandom, clientEncryptedRandom, clientRandomMessage, serverEncryptedRandom, serverRandom, clientSessionKey, serverSessionKey, clientCipher, serverCipher, serverHash, clientHash, serverHashReceived, i, subtype, waitCredentials, username, password, credentials, _i, _i2; | ||
return _regeneratorRuntime().wrap(function _callee4$(_context4) { | ||
while (1) switch (_context4.prev = _context4.next) { | ||
case 0: | ||
this._hasStarted = true; | ||
// 1: Receive server public key | ||
_context13.next = 3; | ||
_context4.next = 3; | ||
return this._waitSockAsync(4); | ||
case 3: | ||
serverKeyLengthBuffer = this._sock.rQslice(0, 4); | ||
serverKeyLengthBuffer = this._sock.rQpeekBytes(4); | ||
serverKeyLength = this._sock.rQshift32(); | ||
if (!(serverKeyLength < 1024)) { | ||
_context13.next = 9; | ||
_context4.next = 9; | ||
break; | ||
@@ -762,3 +265,3 @@ } | ||
if (!(serverKeyLength > 8192)) { | ||
_context13.next = 11; | ||
_context4.next = 11; | ||
break; | ||
@@ -769,3 +272,3 @@ } | ||
serverKeyBytes = Math.ceil(serverKeyLength / 8); | ||
_context13.next = 14; | ||
_context4.next = 14; | ||
return this._waitSockAsync(serverKeyBytes * 2); | ||
@@ -775,4 +278,11 @@ case 14: | ||
serverE = this._sock.rQshiftBytes(serverKeyBytes); | ||
serverRSACipher = new RSACipher(serverKeyLength); | ||
serverRSACipher.setPublicKey(serverN, serverE); | ||
_context4.next = 18; | ||
return _crypto["default"].importKey("raw", { | ||
n: serverN, | ||
e: serverE | ||
}, { | ||
name: "RSA-PKCS1-v1_5" | ||
}, false, ["encrypt"]); | ||
case 18: | ||
serverRSACipher = _context4.sent; | ||
serverPublickey = new Uint8Array(4 + serverKeyBytes * 2); | ||
@@ -784,2 +294,3 @@ serverPublickey.set(serverKeyLengthBuffer); | ||
// verify server public key | ||
approveKey = this._waitApproveKeyAsync(); | ||
this.dispatchEvent(new CustomEvent("serververification", { | ||
@@ -791,14 +302,22 @@ detail: { | ||
})); | ||
_context13.next = 25; | ||
return this._waitApproveKeyAsync(); | ||
case 25: | ||
_context4.next = 27; | ||
return approveKey; | ||
case 27: | ||
// 2: Send client public key | ||
clientKeyLength = 2048; | ||
clientKeyBytes = Math.ceil(clientKeyLength / 8); | ||
clientRSACipher = new RSACipher(clientKeyLength); | ||
_context13.next = 30; | ||
return clientRSACipher.generateKey(); | ||
case 30: | ||
clientN = clientRSACipher.n; | ||
clientE = clientRSACipher.e; | ||
_context4.next = 31; | ||
return _crypto["default"].generateKey({ | ||
name: "RSA-PKCS1-v1_5", | ||
modulusLength: clientKeyLength, | ||
publicExponent: new Uint8Array([1, 0, 1]) | ||
}, true, ["encrypt"]); | ||
case 31: | ||
clientRSACipher = _context4.sent.privateKey; | ||
_context4.next = 34; | ||
return _crypto["default"].exportKey("raw", clientRSACipher); | ||
case 34: | ||
clientExportedRSAKey = _context4.sent; | ||
clientN = clientExportedRSAKey.n; | ||
clientE = clientExportedRSAKey.e; | ||
clientPublicKey = new Uint8Array(4 + clientKeyBytes * 2); | ||
@@ -811,3 +330,4 @@ clientPublicKey[0] = (clientKeyLength & 0xff000000) >>> 24; | ||
clientPublicKey.set(clientE, 4 + clientKeyBytes); | ||
this._sock.send(clientPublicKey); | ||
this._sock.sQpushBytes(clientPublicKey); | ||
this._sock.flush(); | ||
@@ -817,3 +337,8 @@ // 3: Send client random | ||
window.crypto.getRandomValues(clientRandom); | ||
clientEncryptedRandom = serverRSACipher.encrypt(clientRandom); | ||
_context4.next = 50; | ||
return _crypto["default"].encrypt({ | ||
name: "RSA-PKCS1-v1_5" | ||
}, serverRSACipher, clientRandom); | ||
case 50: | ||
clientEncryptedRandom = _context4.sent; | ||
clientRandomMessage = new Uint8Array(2 + serverKeyBytes); | ||
@@ -823,22 +348,28 @@ clientRandomMessage[0] = (serverKeyBytes & 0xff00) >>> 8; | ||
clientRandomMessage.set(clientEncryptedRandom, 2); | ||
this._sock.send(clientRandomMessage); | ||
this._sock.sQpushBytes(clientRandomMessage); | ||
this._sock.flush(); | ||
// 4: Receive server random | ||
_context13.next = 50; | ||
_context4.next = 59; | ||
return this._waitSockAsync(2); | ||
case 50: | ||
case 59: | ||
if (!(this._sock.rQshift16() !== clientKeyBytes)) { | ||
_context13.next = 52; | ||
_context4.next = 61; | ||
break; | ||
} | ||
throw new Error("RA2: wrong encrypted message length"); | ||
case 52: | ||
case 61: | ||
serverEncryptedRandom = this._sock.rQshiftBytes(clientKeyBytes); | ||
serverRandom = clientRSACipher.decrypt(serverEncryptedRandom); | ||
_context4.next = 64; | ||
return _crypto["default"].decrypt({ | ||
name: "RSA-PKCS1-v1_5" | ||
}, clientRSACipher, serverEncryptedRandom); | ||
case 64: | ||
serverRandom = _context4.sent; | ||
if (!(serverRandom === null || serverRandom.length !== 16)) { | ||
_context13.next = 56; | ||
_context4.next = 67; | ||
break; | ||
} | ||
throw new Error("RA2: corrupted server encrypted random"); | ||
case 56: | ||
case 67: | ||
// 5: Compute session keys and set ciphers | ||
@@ -851,20 +382,20 @@ clientSessionKey = new Uint8Array(32); | ||
serverSessionKey.set(serverRandom, 16); | ||
_context13.next = 64; | ||
_context4.next = 75; | ||
return window.crypto.subtle.digest("SHA-1", clientSessionKey); | ||
case 64: | ||
clientSessionKey = _context13.sent; | ||
case 75: | ||
clientSessionKey = _context4.sent; | ||
clientSessionKey = new Uint8Array(clientSessionKey).slice(0, 16); | ||
_context13.next = 68; | ||
_context4.next = 79; | ||
return window.crypto.subtle.digest("SHA-1", serverSessionKey); | ||
case 68: | ||
serverSessionKey = _context13.sent; | ||
case 79: | ||
serverSessionKey = _context4.sent; | ||
serverSessionKey = new Uint8Array(serverSessionKey).slice(0, 16); | ||
clientCipher = new RA2Cipher(); | ||
_context13.next = 73; | ||
_context4.next = 84; | ||
return clientCipher.setKey(clientSessionKey); | ||
case 73: | ||
case 84: | ||
serverCipher = new RA2Cipher(); | ||
_context13.next = 76; | ||
_context4.next = 87; | ||
return serverCipher.setKey(serverSessionKey); | ||
case 76: | ||
case 87: | ||
// 6: Compute and exchange hashes | ||
@@ -877,75 +408,77 @@ serverHash = new Uint8Array(8 + serverKeyBytes * 2 + clientKeyBytes * 2); | ||
clientHash.set(serverPublickey, 4 + clientKeyBytes * 2); | ||
_context13.next = 84; | ||
_context4.next = 95; | ||
return window.crypto.subtle.digest("SHA-1", serverHash); | ||
case 84: | ||
serverHash = _context13.sent; | ||
_context13.next = 87; | ||
case 95: | ||
serverHash = _context4.sent; | ||
_context4.next = 98; | ||
return window.crypto.subtle.digest("SHA-1", clientHash); | ||
case 87: | ||
clientHash = _context13.sent; | ||
case 98: | ||
clientHash = _context4.sent; | ||
serverHash = new Uint8Array(serverHash); | ||
clientHash = new Uint8Array(clientHash); | ||
_context13.t0 = this._sock; | ||
_context13.next = 93; | ||
_context4.t0 = this._sock; | ||
_context4.next = 104; | ||
return clientCipher.makeMessage(clientHash); | ||
case 93: | ||
_context13.t1 = _context13.sent; | ||
_context13.t0.send.call(_context13.t0, _context13.t1); | ||
_context13.next = 97; | ||
case 104: | ||
_context4.t1 = _context4.sent; | ||
_context4.t0.sQpushBytes.call(_context4.t0, _context4.t1); | ||
this._sock.flush(); | ||
_context4.next = 109; | ||
return this._waitSockAsync(2 + 20 + 16); | ||
case 97: | ||
case 109: | ||
if (!(this._sock.rQshift16() !== 20)) { | ||
_context13.next = 99; | ||
_context4.next = 111; | ||
break; | ||
} | ||
throw new Error("RA2: wrong server hash"); | ||
case 99: | ||
_context13.next = 101; | ||
return serverCipher.receiveMessage(20, this._sock.rQshiftBytes(20), this._sock.rQshiftBytes(16)); | ||
case 101: | ||
serverHashReceived = _context13.sent; | ||
case 111: | ||
_context4.next = 113; | ||
return serverCipher.receiveMessage(20, this._sock.rQshiftBytes(20 + 16)); | ||
case 113: | ||
serverHashReceived = _context4.sent; | ||
if (!(serverHashReceived === null)) { | ||
_context13.next = 104; | ||
_context4.next = 116; | ||
break; | ||
} | ||
throw new Error("RA2: failed to authenticate the message"); | ||
case 104: | ||
case 116: | ||
i = 0; | ||
case 105: | ||
case 117: | ||
if (!(i < 20)) { | ||
_context13.next = 111; | ||
_context4.next = 123; | ||
break; | ||
} | ||
if (!(serverHashReceived[i] !== serverHash[i])) { | ||
_context13.next = 108; | ||
_context4.next = 120; | ||
break; | ||
} | ||
throw new Error("RA2: wrong server hash"); | ||
case 108: | ||
case 120: | ||
i++; | ||
_context13.next = 105; | ||
_context4.next = 117; | ||
break; | ||
case 111: | ||
_context13.next = 113; | ||
case 123: | ||
_context4.next = 125; | ||
return this._waitSockAsync(2 + 1 + 16); | ||
case 113: | ||
case 125: | ||
if (!(this._sock.rQshift16() !== 1)) { | ||
_context13.next = 115; | ||
_context4.next = 127; | ||
break; | ||
} | ||
throw new Error("RA2: wrong subtype"); | ||
case 115: | ||
_context13.next = 117; | ||
return serverCipher.receiveMessage(1, this._sock.rQshiftBytes(1), this._sock.rQshiftBytes(16)); | ||
case 117: | ||
subtype = _context13.sent; | ||
case 127: | ||
_context4.next = 129; | ||
return serverCipher.receiveMessage(1, this._sock.rQshiftBytes(1 + 16)); | ||
case 129: | ||
subtype = _context4.sent; | ||
if (!(subtype === null)) { | ||
_context13.next = 120; | ||
_context4.next = 132; | ||
break; | ||
} | ||
throw new Error("RA2: failed to authenticate the message"); | ||
case 120: | ||
case 132: | ||
subtype = subtype[0]; | ||
waitCredentials = this._waitCredentialsAsync(subtype); | ||
if (!(subtype === 1)) { | ||
_context13.next = 125; | ||
_context4.next = 138; | ||
break; | ||
@@ -960,7 +493,7 @@ } | ||
} | ||
_context13.next = 130; | ||
_context4.next = 143; | ||
break; | ||
case 125: | ||
case 138: | ||
if (!(subtype === 2)) { | ||
_context13.next = 129; | ||
_context4.next = 142; | ||
break; | ||
@@ -975,10 +508,10 @@ } | ||
} | ||
_context13.next = 130; | ||
_context4.next = 143; | ||
break; | ||
case 129: | ||
case 142: | ||
throw new Error("RA2: wrong subtype"); | ||
case 130: | ||
_context13.next = 132; | ||
return this._waitCredentialsAsync(subtype); | ||
case 132: | ||
case 143: | ||
_context4.next = 145; | ||
return waitCredentials; | ||
case 145: | ||
if (subtype === 1) { | ||
@@ -993,19 +526,20 @@ username = (0, _strings.encodeUTF8)(this._getCredentials().username).slice(0, 255); | ||
credentials[username.length + 1] = password.length; | ||
for (_i3 = 0; _i3 < username.length; _i3++) { | ||
credentials[_i3 + 1] = username.charCodeAt(_i3); | ||
for (_i = 0; _i < username.length; _i++) { | ||
credentials[_i + 1] = username.charCodeAt(_i); | ||
} | ||
for (_i4 = 0; _i4 < password.length; _i4++) { | ||
credentials[username.length + 2 + _i4] = password.charCodeAt(_i4); | ||
for (_i2 = 0; _i2 < password.length; _i2++) { | ||
credentials[username.length + 2 + _i2] = password.charCodeAt(_i2); | ||
} | ||
_context13.t2 = this._sock; | ||
_context13.next = 142; | ||
_context4.t2 = this._sock; | ||
_context4.next = 155; | ||
return clientCipher.makeMessage(credentials); | ||
case 142: | ||
_context13.t3 = _context13.sent; | ||
_context13.t2.send.call(_context13.t2, _context13.t3); | ||
case 144: | ||
case 155: | ||
_context4.t3 = _context4.sent; | ||
_context4.t2.sQpushBytes.call(_context4.t2, _context4.t3); | ||
this._sock.flush(); | ||
case 158: | ||
case "end": | ||
return _context13.stop(); | ||
return _context4.stop(); | ||
} | ||
}, _callee13, this); | ||
}, _callee4, this); | ||
})); | ||
@@ -1012,0 +546,0 @@ function negotiateRA2neAuthAsync() { |
@@ -13,3 +13,7 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* noVNC: HTML5 VNC client | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 or any later version (see LICENSE.txt) | ||
*/ | ||
var useFallback = !_browser.supportsCursorURIs || _browser.isTouchDevice; | ||
@@ -16,0 +20,0 @@ var Cursor = /*#__PURE__*/function () { |
@@ -21,3 +21,15 @@ "use strict"; | ||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } | ||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /* | ||
* Websock: high-performance buffering wrapper | ||
* Copyright (C) 2019 The noVNC Authors | ||
* Licensed under MPL 2.0 (see LICENSE.txt) | ||
* | ||
* Websock is similar to the standard WebSocket / RTCDataChannel object | ||
* but with extra buffer handling. | ||
* | ||
* Websock has built-in receive queue buffering; the message event | ||
* does not contain actual data but is simply a notification that | ||
* there is new data available. Several rQ* methods are available to | ||
* read binary data off of the receive queue. | ||
*/ | ||
// this has performance issues in some versions Chromium, and | ||
@@ -89,28 +101,5 @@ // doesn't gain a tremendous amount of performance increase in Firefox | ||
} | ||
}, { | ||
key: "sQ", | ||
get: function get() { | ||
return this._sQ; | ||
} | ||
}, { | ||
key: "rQ", | ||
get: function get() { | ||
return this._rQ; | ||
} | ||
}, { | ||
key: "rQi", | ||
get: function get() { | ||
return this._rQi; | ||
}, | ||
set: function set(val) { | ||
this._rQi = val; | ||
} | ||
// Receive Queue | ||
}, { | ||
key: "rQlen", | ||
get: function get() { | ||
return this._rQlen - this._rQi; | ||
} | ||
}, { | ||
key: "rQpeek8", | ||
@@ -149,3 +138,3 @@ value: function rQpeek8() { | ||
} | ||
return res; | ||
return res >>> 0; | ||
} | ||
@@ -155,9 +144,6 @@ }, { | ||
value: function rQshiftStr(len) { | ||
if (typeof len === 'undefined') { | ||
len = this.rQlen; | ||
} | ||
var str = ""; | ||
// Handle large arrays in steps to avoid long strings on the stack | ||
for (var i = 0; i < len; i += 4096) { | ||
var part = this.rQshiftBytes(Math.min(4096, len - i)); | ||
var part = this.rQshiftBytes(Math.min(4096, len - i), false); | ||
str += String.fromCharCode.apply(null, part); | ||
@@ -170,7 +156,9 @@ } | ||
value: function rQshiftBytes(len) { | ||
if (typeof len === 'undefined') { | ||
len = this.rQlen; | ||
var copy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
this._rQi += len; | ||
if (copy) { | ||
return this._rQ.slice(this._rQi - len, this._rQi); | ||
} else { | ||
return this._rQ.subarray(this._rQi - len, this._rQi); | ||
} | ||
this._rQi += len; | ||
return new Uint8Array(this._rQ.buffer, this._rQi - len, len); | ||
} | ||
@@ -180,5 +168,2 @@ }, { | ||
value: function rQshiftTo(target, len) { | ||
if (len === undefined) { | ||
len = this.rQlen; | ||
} | ||
// TODO: make this just use set with views when using a ArrayBuffer to store the rQ | ||
@@ -189,6 +174,10 @@ target.set(new Uint8Array(this._rQ.buffer, this._rQi, len)); | ||
}, { | ||
key: "rQslice", | ||
value: function rQslice(start) { | ||
var end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.rQlen; | ||
return new Uint8Array(this._rQ.buffer, this._rQi + start, end - start); | ||
key: "rQpeekBytes", | ||
value: function rQpeekBytes(len) { | ||
var copy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
if (copy) { | ||
return this._rQ.slice(this._rQi, this._rQi + len); | ||
} else { | ||
return this._rQ.subarray(this._rQi, this._rQi + len); | ||
} | ||
} | ||
@@ -202,3 +191,3 @@ | ||
value: function rQwait(msg, num, goback) { | ||
if (this.rQlen < num) { | ||
if (this._rQlen - this._rQi < num) { | ||
if (goback) { | ||
@@ -218,6 +207,50 @@ if (this._rQi < goback) { | ||
}, { | ||
key: "sQpush8", | ||
value: function sQpush8(num) { | ||
this._sQensureSpace(1); | ||
this._sQ[this._sQlen++] = num; | ||
} | ||
}, { | ||
key: "sQpush16", | ||
value: function sQpush16(num) { | ||
this._sQensureSpace(2); | ||
this._sQ[this._sQlen++] = num >> 8 & 0xff; | ||
this._sQ[this._sQlen++] = num >> 0 & 0xff; | ||
} | ||
}, { | ||
key: "sQpush32", | ||
value: function sQpush32(num) { | ||
this._sQensureSpace(4); | ||
this._sQ[this._sQlen++] = num >> 24 & 0xff; | ||
this._sQ[this._sQlen++] = num >> 16 & 0xff; | ||
this._sQ[this._sQlen++] = num >> 8 & 0xff; | ||
this._sQ[this._sQlen++] = num >> 0 & 0xff; | ||
} | ||
}, { | ||
key: "sQpushString", | ||
value: function sQpushString(str) { | ||
var bytes = str.split('').map(function (chr) { | ||
return chr.charCodeAt(0); | ||
}); | ||
this.sQpushBytes(new Uint8Array(bytes)); | ||
} | ||
}, { | ||
key: "sQpushBytes", | ||
value: function sQpushBytes(bytes) { | ||
for (var offset = 0; offset < bytes.length;) { | ||
this._sQensureSpace(1); | ||
var chunkSize = this._sQbufferSize - this._sQlen; | ||
if (chunkSize > bytes.length - offset) { | ||
chunkSize = bytes.length - offset; | ||
} | ||
this._sQ.set(bytes.subarray(offset, chunkSize), this._sQlen); | ||
this._sQlen += chunkSize; | ||
offset += chunkSize; | ||
} | ||
} | ||
}, { | ||
key: "flush", | ||
value: function flush() { | ||
if (this._sQlen > 0 && this.readyState === 'open') { | ||
this._websocket.send(this._encodeMessage()); | ||
this._websocket.send(new Uint8Array(this._sQ.buffer, 0, this._sQlen)); | ||
this._sQlen = 0; | ||
@@ -227,15 +260,8 @@ } | ||
}, { | ||
key: "send", | ||
value: function send(arr) { | ||
this._sQ.set(arr, this._sQlen); | ||
this._sQlen += arr.length; | ||
this.flush(); | ||
key: "_sQensureSpace", | ||
value: function _sQensureSpace(bytes) { | ||
if (this._sQbufferSize - this._sQlen < bytes) { | ||
this.flush(); | ||
} | ||
} | ||
}, { | ||
key: "sendString", | ||
value: function sendString(str) { | ||
this.send(str.split('').map(function (chr) { | ||
return chr.charCodeAt(0); | ||
})); | ||
} | ||
@@ -320,9 +346,2 @@ // Event Handlers | ||
// private methods | ||
}, { | ||
key: "_encodeMessage", | ||
value: function _encodeMessage() { | ||
// Put in a binary arraybuffer | ||
// according to the spec, you can send ArrayBufferViews with the send method | ||
return new Uint8Array(this._sQ.buffer, 0, this._sQlen); | ||
} | ||
@@ -333,3 +352,3 @@ // We want to move all the unread data to the start of the queue, | ||
// performance reasons we combine these two actions to avoid | ||
// unneccessary copying. | ||
// unnecessary copying. | ||
}, { | ||
@@ -351,3 +370,3 @@ key: "_expandCompactRQ", | ||
this._rQbufferSize = MAX_RQ_GROW_SIZE; | ||
if (this._rQbufferSize - this.rQlen < minFit) { | ||
if (this._rQbufferSize - (this._rQlen - this._rQi) < minFit) { | ||
throw new Error("Receive Queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); | ||
@@ -369,5 +388,11 @@ } | ||
}, { | ||
key: "_DecodeMessage", | ||
value: function _DecodeMessage(data) { | ||
var u8 = new Uint8Array(data); | ||
key: "_recvMessage", | ||
value: function _recvMessage(e) { | ||
if (this._rQlen == this._rQi) { | ||
// All data has now been processed, this means we | ||
// can reset the receive queue. | ||
this._rQlen = 0; | ||
this._rQi = 0; | ||
} | ||
var u8 = new Uint8Array(e.data); | ||
if (u8.length > this._rQbufferSize - this._rQlen) { | ||
@@ -378,15 +403,4 @@ this._expandCompactRQ(u8.length); | ||
this._rQlen += u8.length; | ||
} | ||
}, { | ||
key: "_recvMessage", | ||
value: function _recvMessage(e) { | ||
this._DecodeMessage(e.data); | ||
if (this.rQlen > 0) { | ||
if (this._rQlen - this._rQi > 0) { | ||
this._eventHandlers.message(); | ||
if (this._rQlen == this._rQi) { | ||
// All data has now been processed, this means we | ||
// can reset the receive queue. | ||
this._rQlen = 0; | ||
this._rQi = 0; | ||
} | ||
} else { | ||
@@ -393,0 +407,0 @@ Log.Debug("Ignoring empty message"); |
{ | ||
"name": "@novnc/novnc", | ||
"version": "1.4.0-beta-gb76358e", | ||
"version": "1.4.0-g295004c", | ||
"description": "An HTML5 VNC client", | ||
@@ -5,0 +5,0 @@ "browser": "lib/rfb", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
1342752
116
31263