diff --git a/package.json b/package.json index 4b8de71..e961591 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "typescript": "^4.6.4" }, "dependencies": { - "@openziti/libcrypto-js": "^0.14.1", + "@openziti/libcrypto-js": "^0.15.0", "@openziti/ziti-browzer-edge-client": "^0.6.0", "asn1js": "^2.4.0", "assert": "^2.0.0", diff --git a/src/channel/channel.js b/src/channel/channel.js index acbdca4..44a2ba4 100644 --- a/src/channel/channel.js +++ b/src/channel/channel.js @@ -236,15 +236,6 @@ class ZitiChannel { if (isEqual(this._callerId, "ws:")) { - // this._zitiContext.ssl_CTX_new(); - // // this._zitiContext.bio_new_ssl_connect(); - // // this._zitiContext.bio_set_conn_hostname('www.google.com:443'); - // // this._zitiContext.bio_do_connect(); - - // this._zitiContext.ssl_new(); - // this._zitiContext.ssl_set_fd( this.id ); - // this._zitiContext.ssl_connect(); - this._tlsConn = new ZitiWASMTLSConnection({ zitiContext: this._zitiContext, ws: this._zws, @@ -259,7 +250,7 @@ class ZitiChannel { this._zitiContext.logger.debug('initiating TLS handshake'); - this._tlsConn.handshake(); + await this._tlsConn.handshake(); await this.awaitTLSHandshakeComplete(); @@ -1045,6 +1036,8 @@ class ZitiChannel { const release = await this._mutex.acquire(); + let zeroByteData = false; + /** * First Data msg for a new connection needs special handling */ @@ -1080,6 +1073,8 @@ class ZitiChannel { if ( isEqual(contentType, ZitiEdgeProtocol.content_type.Data) && isEqual(bodyLength, 0) ) { + zeroByteData = true; + // let result = await this._messageGetBytesHeader(data, ZitiEdgeProtocol.header_id.SeqHeader); // replyForView = new Int32Array(result.data, 0, 1); // responseSequence = replyForView[0]; @@ -1104,74 +1099,79 @@ class ZitiChannel { let connId = await this._messageGetConnId(data); throwIf(isUndefined(connId), formatMessage('Cannot find ConnId header', { } ) ); conn = this._connections._getConnection(connId); - throwIf(isUndefined(conn), formatMessage('Conn not found. Seeking connId { actual }', { actual: connId}) ); + if (!zeroByteData) { + throwIf(isUndefined(conn), formatMessage('Conn not found. Seeking connId { actual }', { actual: connId}) ); + } } - + /** * Data msgs might need to be decrypted before passing along */ if (contentType == ZitiEdgeProtocol.content_type.Data) { - if (bodyLength > 0) { + if (!isUndefined(conn)) { - if (conn.encrypted && conn.cryptoEstablishComplete) { // if connected to a service that has 'encryptionRequired' + if (bodyLength > 0) { - let unencrypted_data = sodium.crypto_secretstream_xchacha20poly1305_pull(conn.crypt_i, bodyView); + if (conn.encrypted && conn.cryptoEstablishComplete) { // if connected to a service that has 'encryptionRequired' - if (!unencrypted_data) { - this._zitiContext.logger.error("crypto_secretstream_xchacha20poly1305_pull failed. bodyLength[%d]", bodyLength); - } + let unencrypted_data = sodium.crypto_secretstream_xchacha20poly1305_pull(conn.crypt_i, bodyView); - try { - let [m1, tag1] = [sodium.to_string(unencrypted_data.message), unencrypted_data.tag]; - let len = m1.length; - if (len > 2000) { - len = 2000; + if (!unencrypted_data) { + this._zitiContext.logger.error("crypto_secretstream_xchacha20poly1305_pull failed. bodyLength[%d]", bodyLength); } - // this._zitiContext.logger.trace("recv <- unencrypted_data (first 2000): %s", m1.substring(0, len)); - // - // let dbgStr = m1.substring(0, len); - // this._zitiContext.logger.trace("recv <- data (first 2000): %s", dbgStr); + try { + let [m1, tag1] = [sodium.to_string(unencrypted_data.message), unencrypted_data.tag]; + let len = m1.length; + if (len > 2000) { + len = 2000; + } + // this._zitiContext.logger.trace("recv <- unencrypted_data (first 2000): %s", m1.substring(0, len)); - } catch (e) { } + // + // let dbgStr = m1.substring(0, len); + // this._zitiContext.logger.trace("recv <- data (first 2000): %s", dbgStr); - bodyView = unencrypted_data.message; - } else { - /* debug... - let len = bodyView.length; - if (len > 2000) { - len = 2000; - } - let dbgStr = String.fromCharCode.apply(null, bodyView).substring(0, len); - this._zitiContext.logger.debug("recv <- data (first 2000): %s", dbgStr); - */ + } catch (e) { } + + bodyView = unencrypted_data.message; + } else { + /* debug... + let len = bodyView.length; + if (len > 2000) { + len = 2000; + } + let dbgStr = String.fromCharCode.apply(null, bodyView).substring(0, len); + this._zitiContext.logger.debug("recv <- data (first 2000): %s", dbgStr); + */ - //temp debugging - // if (dbgStr.includes("var openMe = (window.parent")) { + //temp debugging + // if (dbgStr.includes("var openMe = (window.parent")) { - // let str = String.fromCharCode.apply(null, bodyView).substring(0, bodyView.length); + // let str = String.fromCharCode.apply(null, bodyView).substring(0, bodyView.length); - // // str = str.replace('var openMe = (window.parent', 'debugger; var openMe = (window.parent'); + // // str = str.replace('var openMe = (window.parent', 'debugger; var openMe = (window.parent'); - // if (str.indexOf( '/api/extplugins/config' ) !== -1) { - // debugger - // } + // if (str.indexOf( '/api/extplugins/config' ) !== -1) { + // debugger + // } - // this._zitiContext.logger.debug("============== DEBUG INJECT: %s", str); + // this._zitiContext.logger.debug("============== DEBUG INJECT: %s", str); - // bodyView = new TextEncoder("utf-8").encode(str); - - // } + // bodyView = new TextEncoder("utf-8").encode(str); + + // } + } } - } - // - let dataCallback = conn.dataCallback; - if (!isUndefined(dataCallback)) { - this._zitiContext.logger.debug("recv <- conn[%o] contentType[%o] seq[%o] passing body to dataCallback", conn.id, contentType, sequenceView[0]); - dataCallback(conn, bodyView); + // + let dataCallback = conn.dataCallback; + if (!isUndefined(dataCallback)) { + this._zitiContext.logger.debug("recv <- conn[%o] contentType[%o] seq[%o] passing body to dataCallback", conn.id, contentType, sequenceView[0]); + dataCallback(conn, bodyView); + } } } diff --git a/src/channel/tls-connection.js b/src/channel/tls-connection.js index e6892db..215c9ed 100644 --- a/src/channel/tls-connection.js +++ b/src/channel/tls-connection.js @@ -61,7 +61,7 @@ import { v4 as uuidv4 } from 'uuid'; */ async pullKeyPair() { - this._privateKeyPEM = this._zitiContext.privateKeyPEM; + this._privateKeyPEM = this._zitiContext.get_privateKeyPEM(); this._certPEM = await this._zitiContext.getCertPEM(); diff --git a/src/channel/wasm-tls-connection.js b/src/channel/wasm-tls-connection.js index 6509644..16f21c0 100644 --- a/src/channel/wasm-tls-connection.js +++ b/src/channel/wasm-tls-connection.js @@ -47,7 +47,7 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; this._id = this._ch.id; this._datacb = this._options.datacb; - this._connected_cb = null; + // this._connected_cb = null; this._connected = false; this._read_cb = null; @@ -98,7 +98,7 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; */ async pullKeyPair() { - this._privateKeyPEM = this._zitiContext.privateKeyPEM; + this._privateKeyPEM = this._zitiContext.get_privateKeyPEM(); this._certPEM = await this._zitiContext.getCertPEM(); @@ -123,17 +123,21 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; */ async create() { - this._sslContext = await this._zitiContext.ssl_CTX_new(); + this._wasmInstance = await this._zitiContext.getInstance_OuterWASM(); - this._BIO = this._zitiContext.bio_new_ssl_connect(this._sslContext); + this._sslContext = await this._zitiContext.ssl_CTX_new( this._wasmInstance ); - this._SSL = this._zitiContext.bio_get_ssl(this._BIO); + this._zitiContext.logger.trace('ZitiWASMTLSConnection.create() _zitiContext.ssl_CTX_new() returned [%o]', this._sslContext); + + this._BIO = this._zitiContext.bio_new_ssl_connect(this._wasmInstance, this._sslContext); + + this._SSL = this._zitiContext.bio_get_ssl(this._wasmInstance, this._BIO); // Tie the WASM-based SSL object back to this ZitiWASMTLSConnection so that later when - // the low-level WASM code does fd-level i/o, our WAS-JS will intercept it, and + // the low-level WASM code does fd-level i/o, our WASM-JS will intercept it, and // interface with this connection, so we can route traffic over the WebSocket to the ER - this._zitiContext.ssl_set_fd( this._SSL, this._ch.id ); + this._zitiContext.ssl_set_fd( this._wasmInstance, this._SSL, this._ch.id ); } @@ -174,46 +178,59 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; /** * */ - handshake_cb(self, rc) { - self._zitiContext.logger.trace('ZitiWASMTLSConnection.handshake_cb(): entered rc=%d ', rc ); - - // Let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, - // before we turn loose any writes to the connection - setTimeout((tlsConn, rc) => { - self._zitiContext.logger.trace("ZitiWASMTLSConnection.handshake_cb(): after timeout"); - self._connected = true; - }, 500, self, rc) - } + // handshake_cb(self, rc) { + // self._zitiContext.logger.trace('ZitiWASMTLSConnection.handshake_cb(): entered rc=%d ', rc ); + + // // Let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, + // // before we turn loose any writes to the connection + // setTimeout((tlsConn, rc) => { + // self._zitiContext.logger.trace("ZitiWASMTLSConnection.handshake_cb(): after timeout"); + // self._connected = true; + // }, 500, self, rc) + // } /** * */ - handshake() { + async handshake() { // Make sure WASM knows where to callback to once handshake is complete - this._connected_cb = this.handshake_cb; - - + // this._connected_cb = this.handshake_cb; this._zitiContext.logger.trace('ZitiWASMTLSConnection.handshake(): fd[%d] calling ssl_do_handshake()', this.wasmFD ); - let result = this._zitiContext.ssl_do_handshake( this._SSL ); + let result = this._zitiContext.ssl_do_handshake( this._wasmInstance, this._SSL ); this._zitiContext.logger.trace('ZitiWASMTLSConnection.handshake(): fd[%d] back from ssl_do_handshake() for %o: result=%d (now awaiting cb)', this.wasmFD, this._id, result ); } - ssl_get_verify_result() { - let result = this._zitiContext.ssl_get_verify_result( this._SSL ); - this._zitiContext.logger.trace('ZitiWASMTLSConnection.ssl_get_verify_result(): for: %o: result: ', this._id, result ); - return result; - } + // ssl_get_verify_result() { + // let result = this._zitiContext.ssl_get_verify_result( this._SSL ); + // this._zitiContext.logger.trace('ZitiWASMTLSConnection.ssl_get_verify_result(): for: %o: result: ', this._id, result ); + // return result; + // } /** * */ get connected() { - return this._connected; - } - set connected(state) { - this._connected = state; + + // If we already did the work, and are fully connected, take a quick exit + if (this._connected) return true; + + // Ask the SSL if its handshake has completed yet + let _connected = this._zitiContext.ssl_is_init_finished(this._wasmInstance, this._SSL); + + // If SSL indicates handshake has completed, let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, + // before we turn loose any writes to the connection + if (_connected) { + + setTimeout((self) => { + self._zitiContext.logger.trace("ZitiWASMTLSConnection.connected(): after timeout"); + self._connected = true; + }, 100, this); + + } + + return this._connected } @@ -246,16 +263,16 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; async process(arrayBuffer) { this._zitiContext.logger.trace('ZitiWASMTLSConnection.process[%d] encrypted data from the ER arrived <--- [%o]', this.wasmFD, arrayBuffer); - await this._zitiContext.tls_enqueue(this.wasmFD, arrayBuffer); // enqueue the encrypted data (place it in WASM memory) + await this._zitiContext.tls_enqueue(this._wasmInstance, this.wasmFD, arrayBuffer); // enqueue the encrypted data (place it in WASM memory) // If the TLS handshake has completed, we'll need to do TLS-decrypt of the data, // and then propagate it to the Promise that is waiting for it. - if (this._connected) { + if (this.connected) { // Make sure WASM knows where to callback when decrypted data is ready // this._read_cb = this.read_cb; - let decryptedData = this._zitiContext.tls_read(this._SSL); // TLS-decrypt some data from the queue (bring back from WASM memory into JS memory) + let decryptedData = this._zitiContext.tls_read(this._wasmInstance, this._SSL); // TLS-decrypt some data from the queue (bring back from WASM memory into JS memory) this._zitiContext.logger.trace('ZitiWASMTLSConnection.process[%d]: clear data from the ER is ready <--- len[%d]', this.wasmFD, decryptedData.byteLength); this._datacb(this._ch, decryptedData.buffer); // propagate clear data to the waiting Promise @@ -277,7 +294,7 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; * * @param {*} wireData (not TLS-encrypted yet) */ - tls_write(wireData, conn) { + async tls_write(wireData, conn) { this._zitiContext.logger.trace(`ZitiWASMTLSConnection.tls_write unencrypted data is ready to be sent to the ER ---> len[${wireData.byteLength}]`); // If connection has an innerTLSsocket, and it has completed its TLS handshake @@ -287,7 +304,7 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; // ...then pass it to the Channel this._zitiContext.logger.trace(`ZitiWASMTLSConnection.tls_write sending encrypted wireData from innerTLSSocket to _zitiContext.tls_write`); conn._socket.innerTLSSocket._sendingEncryptedData = false; // reset now that we're sending to outer socket - this._zitiContext.tls_write(this._SSL, wireData); + this._zitiContext.tls_write(this._wasmInstance, this._SSL, wireData); } else { // ...otherwise pass it to the innerTLSsocket so it can do the necessary TLS encryption according to the handshake that was completed with // the connected service (i.e. web server listening on TLS) @@ -295,7 +312,7 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; conn._socket.innerTLSSocket.tls_write(wireData); } } else { - this._zitiContext.tls_write(this._SSL, wireData); + this._zitiContext.tls_write(this._wasmInstance, this._SSL, wireData); } } @@ -303,10 +320,10 @@ import {Mutex, withTimeout, Semaphore} from 'async-mutex'; * * @param {*} wireData (TLS-encrypted at the innerTLS level, but not TLS-encrypted at mTLS level yet) */ - tls_write_outer(wireData) { - this._zitiContext.logger.trace('ZitiWASMTLSConnection.tls_write_outer[%o] unencrypted data is ready to be sent to the ER ---> [%o]', this._uuid, wireData); - this._zitiContext.tls_write(this._SSL, wireData.buffer); - } + // tls_write_outer(wireData) { + // this._zitiContext.logger.trace('ZitiWASMTLSConnection.tls_write_outer[%o] unencrypted data is ready to be sent to the ER ---> [%o]', this._uuid, wireData); + // this._zitiContext.tls_write(this._SSL, wireData.buffer); + // } /** * diff --git a/src/context/context.js b/src/context/context.js index e8fb19e..bd4c0a2 100644 --- a/src/context/context.js +++ b/src/context/context.js @@ -66,6 +66,7 @@ class ZitiContext extends EventEmitter { super(); this._initialized = false; + this._initializedInnerWASM = false; let _options = flatOptions(options, defaultOptions); @@ -117,8 +118,10 @@ class ZitiContext extends EventEmitter { this._connectMutexWithTimeout = withTimeout(new Mutex(), 30 * 1000); - // this._fetchSemaphore = new Semaphore( 8 ); + this._tlsHandshakeLock = withTimeout(new Mutex(), 5 * 1000, new Error('timeout on _tlsHandshakeLock')); + this._fetchSemaphore = new Semaphore( 8 ); + // this._fetchSemaphore = new Semaphore( 1 ); this._pkey = null; this._privateKeyPEM = null; @@ -164,19 +167,23 @@ class ZitiContext extends EventEmitter { if (options.loadWASM) { - this.logger.trace(`libCrypto.initialize starting`); + this.logger.trace(`libCrypto.initialize_OuterWASM starting`); let _real_Date_now = Date.now; // work around an Emscripten issue - await this._libCrypto.initialize(); + await this._libCrypto.initialize_OuterWASM(); Date.now = _real_Date_now; // work around an Emscripten issue - this.logger.trace(`libCrypto.initialize completed; WASM is now available`); + this.logger.trace(`libCrypto.initialize_OuterWASM completed; outer WASM is now available`); + + if (isEqual(options.target.scheme, 'https')) { + this.initialize_InnerWASM(); + } } else { - this.logger.trace(`libCrypto.initialize bypassed (options.loadWASM is false)`); + this.logger.trace(`libCrypto.initialize_OuterWASM bypassed (options.loadWASM is false)`); } @@ -189,6 +196,48 @@ class ZitiContext extends EventEmitter { } + /** + * + */ + async initialize_InnerWASM() { + + if (this._initializedInnerWASM) throw Error("Already initialized; Cannot call .initialize_InnerWASM() twice on instance."); + + this.logger.trace(`libCrypto.initialize_InnerWASM starting`); + + let _real_Date_now = Date.now; // work around an Emscripten issue + + await this._libCrypto.initialize_InnerWASM(); + + Date.now = _real_Date_now; // work around an Emscripten issue + + this.logger.trace(`libCrypto.initialize_InnerWASM completed; Inner WASM is now available`); + + this._initializedInnerWASM = true; + + } + + /** + * + */ + async getInstance_OuterWASM() { + + let instance_outerWASM = await this._libCrypto.getInstance_OuterWASM(); + + return instance_outerWASM; + + } + + /** + * + */ + async getInstance_InnerWASM() { + + let instance_innerWASM = await this._libCrypto.getInstance_InnerWASM(); + + return instance_innerWASM; + + } /** * @@ -227,13 +276,13 @@ class ZitiContext extends EventEmitter { /** * */ - generateRSAKey() { + async generateRSAKey() { this.logger.trace('ZitiContext.generateRSAKey() entered'); if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - this._pkey = this._libCrypto.generateKey({}); + this._pkey = this._libCrypto.generateKey( await this.getInstance_OuterWASM() ); this.logger.trace('ZitiContext.generateRSAKey() exiting'); @@ -243,37 +292,29 @@ class ZitiContext extends EventEmitter { /** * */ - generateECKey() { + async generateECKey() { this.logger.trace('ZitiContext.generateECKey() entered'); if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - this._pkey = this._libCrypto.generateECKey({}); + let wasmInstance = await this.getInstance_OuterWASM(); - this.logger.trace('ZitiContext.generateECKey() exiting'); + this._pkey = this._libCrypto.generateECKey( wasmInstance ); - return this._pkey; - } - - /** - * - */ - freeECKey(pkey) { - - if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); + this.logger.trace(`ZitiContext.generateECKey() exiting, pkey[${this._pkey}]`); - this._libCrypto.freeECKey(pkey); + return this._pkey; } /** * */ - getPrivateKeyPEM(pkey) { + async getPrivateKeyPEM(pkey) { if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - this._privateKeyPEM = this._libCrypto.getPrivateKeyPEM(pkey); + this._privateKeyPEM = this._libCrypto.getPrivateKeyPEM(await this.getInstance_OuterWASM(), pkey); return this._privateKeyPEM; } @@ -281,11 +322,11 @@ class ZitiContext extends EventEmitter { /** * */ - getPublicKeyPEM(pkey) { + async getPublicKeyPEM(pkey) { if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - this._publicKeyPEM = this._libCrypto.getPublicKeyPEM(pkey); + this._publicKeyPEM = this._libCrypto.getPublicKeyPEM(await this.getInstance_OuterWASM(), pkey); return this._publicKeyPEM; } @@ -293,7 +334,7 @@ class ZitiContext extends EventEmitter { /** * */ - createCertificateSigningRequest({ + createCertificateSigningRequest(wasmInstance, { key = null, curve = this._libCrypto.NID_secp521r1, compressed = this._libCrypto.POINT_CONVERSION_UNCOMPRESSED, @@ -309,13 +350,16 @@ class ZitiContext extends EventEmitter { if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - this._csrPEM = this._libCrypto.createCertificateSigningRequest({ - key: key, - curve: curve, - compressed: compressed, - version: version, - name: name - }); + this._csrPEM = this._libCrypto.createCertificateSigningRequest( + wasmInstance, + { + key: key, + curve: curve, + compressed: compressed, + version: version, + name: name + } + ); return this._csrPEM; } @@ -324,11 +368,11 @@ class ZitiContext extends EventEmitter { /** * */ - get rsaKey () { + async get_rsaKey () { if (isNull(this._pkey)) { this.logger.trace('ZitiContext.get rsaKey() needs to genetrate a new key'); - this._pkey = this.generateRSAKey({}); + this._pkey = await this.generateRSAKey(); } return this._pkey; @@ -337,11 +381,11 @@ class ZitiContext extends EventEmitter { /** * */ - get ecKey () { + async get_ecKey() { if (isNull(this._pkey)) { - this.logger.trace('ZitiContext.get ecKey() needs to genetrate a new key'); - this._pkey = this.generateECKey({}); + this.logger.trace('ZitiContext.get ecKey() needs to generate a new key'); + this._pkey = await this.generateECKey(); } return this._pkey; @@ -350,7 +394,7 @@ class ZitiContext extends EventEmitter { /** * */ - get pKey () { + async get_pKey () { if (isNull(this._pkey)) { @@ -358,13 +402,13 @@ class ZitiContext extends EventEmitter { case EVP_PKEY_RSA: { - this._pkey = this.rsaKey; + this._pkey = this.get_rsaKey(); } break; case EVP_PKEY_EC: { - this._pkey = this.ecKey; + this._pkey = await this.get_ecKey(); } break; @@ -380,17 +424,17 @@ class ZitiContext extends EventEmitter { /** * */ - get privateKeyPEM () { + async get_privateKeyPEM () { switch(this._keyType) { case EVP_PKEY_RSA: { if (isNull(this._pkey)) { - this._pkey = this.generateRSAKey({}); + this._pkey = await this.generateRSAKey(); } if (isNull(this._privateKeyPEM)) { - this._privateKeyPEM = this.getPrivateKeyPEM(this._pkey) + this._privateKeyPEM = await this.getPrivateKeyPEM(this._pkey) } } break; @@ -398,10 +442,10 @@ class ZitiContext extends EventEmitter { case EVP_PKEY_EC: { if (isNull(this._pkey)) { - this._pkey = this.generateECKey({}); + this._pkey = await this.generateECKey(); } if (isNull(this._privateKeyPEM)) { - this._privateKeyPEM = this.getPrivateKeyPEM(this._pkey) + this._privateKeyPEM = await this.getPrivateKeyPEM(this._pkey) } } break; @@ -416,17 +460,17 @@ class ZitiContext extends EventEmitter { /** * */ - get publicKeyPEM () { + async get_publicKeyPEM () { switch(this._keyType) { case EVP_PKEY_RSA: { if (isNull(this._pkey)) { - this._pkey = this.generateRSAKey({}); + this._pkey = await this.generateRSAKey(); } if (isNull(this._publicKeyPEM)) { - this._publicKeyPEM = this.getPublicKeyPEM(this._pkey); + this._publicKeyPEM = await this.getPublicKeyPEM(this._pkey); } } break; @@ -434,10 +478,10 @@ class ZitiContext extends EventEmitter { case EVP_PKEY_EC: { if (isNull(this._pkey)) { - this._pkey = this.generateECKey({}); + this._pkey = await this.generateECKey(); } if (isNull(this._publicKeyPEM)) { - this._publicKeyPEM = this.getPublicKeyPEM(this._pkey); + this._publicKeyPEM = await this.getPublicKeyPEM(this._pkey); } } break; @@ -454,18 +498,18 @@ class ZitiContext extends EventEmitter { * * @returns */ - async ssl_CTX_new() { + async ssl_CTX_new( wasmInstance ) { this.logger.trace('ZitiContext.ssl_CTX_new() entered'); if (!this._initialized) throw Error("Not initialized; Must call .initialize() on instance."); - let sslContext = this._libCrypto.ssl_CTX_new(); + let sslContext = this._libCrypto.ssl_CTX_new( wasmInstance ); this.logger.trace('ZitiContext.ssl_CTX_new() _libCrypto.ssl_CTX_new() returned [%o]', sslContext); - await this.ssl_CTX_add_certificate(sslContext); - this.ssl_CTX_add_private_key(sslContext); - this.ssl_CTX_verify_certificate_and_key(sslContext); + await this.ssl_CTX_add_certificate(wasmInstance, sslContext); + await this.ssl_CTX_add_private_key(wasmInstance, sslContext); + this.ssl_CTX_verify_certificate_and_key(wasmInstance, sslContext); this.logger.trace('ZitiContext.ssl_CTX_new() exiting'); @@ -476,11 +520,13 @@ class ZitiContext extends EventEmitter { * * @returns */ - ssl_CTX_add_private_key(sslContext) { + async ssl_CTX_add_private_key(wasmInstance, sslContext) { this.logger.trace('ZitiContext.ssl_CTX_add_private_key() entered'); - sslContext = this._libCrypto.ssl_CTX_add_private_key(sslContext, this.pKey); + let pKey = await this.get_pKey(); + + sslContext = this._libCrypto.ssl_CTX_add_private_key(wasmInstance, sslContext, pKey); if (isNull(sslContext)) throw Error("SSL Context failure."); @@ -493,16 +539,16 @@ class ZitiContext extends EventEmitter { * * @returns */ - async ssl_CTX_add_certificate(sslContext) { + async ssl_CTX_add_certificate(wasmInstance, sslContext) { this.logger.trace('ZitiContext.ssl_CTX_add_certificate() entered'); // Add client cert - sslContext = this._libCrypto.ssl_CTX_add_certificate(sslContext, await this.getCertPEM()); + sslContext = this._libCrypto.ssl_CTX_add_certificate(wasmInstance, sslContext, await this.getCertPEM()); if (isNull(sslContext)) throw Error("SSL Context failure."); // Add CAs - sslContext = this._libCrypto.ssl_CTX_add1_to_CA_list(sslContext, await this.getCasPEM()); + sslContext = this._libCrypto.ssl_CTX_add1_to_CA_list(wasmInstance, sslContext, await this.getCasPEM()); if (isNull(sslContext)) throw Error("SSL Context failure."); this.logger.trace('ZitiContext.ssl_CTX_add_certificate() exiting'); @@ -514,15 +560,15 @@ class ZitiContext extends EventEmitter { * * @returns */ - ssl_CTX_verify_certificate_and_key(sslContext) { + ssl_CTX_verify_certificate_and_key(wasmInstance, sslContext) { this.logger.trace('ZitiContext.ssl_CTX_verify_certificate_and_key() entered'); - sslContext = this._libCrypto.ssl_CTX_verify_certificate_and_key(sslContext); + sslContext = this._libCrypto.ssl_CTX_verify_certificate_and_key(wasmInstance, sslContext); if (isNull(sslContext)) throw Error("SSL Context failure."); - this.logger.trace('ZitiContext.ssl_CTX_add_private_key() exiting'); + this.logger.trace('ZitiContext.ssl_CTX_verify_certificate_and_key() exiting'); return sslContext; } @@ -530,11 +576,11 @@ class ZitiContext extends EventEmitter { /** * */ - bio_new_ssl_connect(sslContext) { + bio_new_ssl_connect(wasmInstance, sslContext) { - this.logger.trace('ZitiContext.bio_new_ssl_connect() entered'); + this.logger.trace('ZitiContext.bio_new_ssl_connect() entered, sslContext: ', sslContext); - let bio = this._libCrypto.bio_new_ssl_connect(sslContext); + let bio = this._libCrypto.bio_new_ssl_connect(wasmInstance, sslContext); if (isNull(bio)) throw Error("bio_new_ssl_connect create failure."); @@ -546,11 +592,11 @@ class ZitiContext extends EventEmitter { /** * */ - bio_get_ssl(bio) { + bio_get_ssl(wasmInstance, bio) { this.logger.trace('ZitiContext.bio_get_ssl() entered'); - let ssl = this._libCrypto.bio_get_ssl(bio); + let ssl = this._libCrypto.bio_get_ssl(wasmInstance, bio); if (isNull(ssl)) throw Error("bio_get_ssl failure."); @@ -562,77 +608,83 @@ class ZitiContext extends EventEmitter { /** * */ - bio_do_connect() { + // bio_do_connect() { - this.logger.trace('ZitiContext.bio_do_connect() entered'); + // this.logger.trace('ZitiContext.bio_do_connect() entered'); - if (!this._sslContext) throw Error("No SSL Context exists; Must call .ssl_CTX_new() on instance."); - if (!this._SSL_BIO) throw Error("No SSL_BIO exists; Must call .bio_new_ssl_connect() on instance."); + // if (!this._sslContext) throw Error("No SSL Context exists; Must call .ssl_CTX_new() on instance."); + // if (!this._SSL_BIO) throw Error("No SSL_BIO exists; Must call .bio_new_ssl_connect() on instance."); - let result = this._libCrypto.bio_do_connect(this._SSL_BIO); + // let result = this._libCrypto.bio_do_connect(this._SSL_BIO); - this.logger.trace('ZitiContext.bio_do_connect() exiting'); + // this.logger.trace('ZitiContext.bio_do_connect() exiting'); - return result; - } + // return result; + // } /** * */ - bio_set_conn_hostname(hostname) { + // bio_set_conn_hostname(hostname) { - this.logger.trace('ZitiContext.bio_set_conn_hostname() entered'); + // this.logger.trace('ZitiContext.bio_set_conn_hostname() entered'); - if (!this._sslContext) throw Error("No SSL Context exists; Must call .ssl_CTX_new() on instance."); - if (!this._SSL_BIO) throw Error("No SSL_BIO exists; Must call .bio_new_ssl_connect() on instance."); + // if (!this._sslContext) throw Error("No SSL Context exists; Must call .ssl_CTX_new() on instance."); + // if (!this._SSL_BIO) throw Error("No SSL_BIO exists; Must call .bio_new_ssl_connect() on instance."); - let result = this._libCrypto.bio_set_conn_hostname(this._SSL_BIO, hostname); + // let result = this._libCrypto.bio_set_conn_hostname(this._SSL_BIO, hostname); - this.logger.trace('ZitiContext.bio_set_conn_hostname() exiting'); + // this.logger.trace('ZitiContext.bio_set_conn_hostname() exiting'); - return result; - } + // return result; + // } /** * */ - ssl_do_handshake(ssl) { + ssl_do_handshake(wasmInstance, ssl) { this.logger.trace('ZitiContext.ssl_do_handshake() entered'); - let result = this._libCrypto.ssl_do_handshake(ssl); + let result = this._libCrypto.ssl_do_handshake(wasmInstance, ssl); this.logger.trace('ZitiContext.ssl_do_handshake() exiting, result=', result); return result; } + + ssl_is_init_finished(wasmInstance, ssl) { + + return this._libCrypto.ssl_is_init_finished(wasmInstance, ssl); + + } /** * * @returns */ - ssl_new(sslContext) { + // ssl_new(sslContext) { - this.logger.trace('ZitiContext.ssl_new() entered'); + // this.logger.trace('ZitiContext.ssl_new() entered'); - let ssl = this._libCrypto.ssl_new(sslContext); + // let ssl = this._libCrypto.ssl_new(sslContext); - if (isNull(ssl)) throw Error("SSL create failure."); + // if (isNull(ssl)) throw Error("SSL create failure."); - this.logger.trace('ZitiContext.ssl_new() exiting'); + // this.logger.trace('ZitiContext.ssl_new() exiting'); - return ssl; - } + // return ssl; + // } /** * * @returns */ - ssl_set_fd(ssl, fd) { + ssl_set_fd(wasmInstance, ssl, fd) { this.logger.trace('ZitiContext.ssl_set_fd() entered'); - let result = this._libCrypto.ssl_set_fd(ssl, fd); + let result = this._libCrypto.ssl_set_fd(wasmInstance, ssl, fd); if (result !== 1) throw Error("ssl_set_fd failure."); @@ -645,38 +697,56 @@ class ZitiContext extends EventEmitter { * * @returns */ - ssl_connect(ssl) { + // ssl_connect(ssl) { - this.logger.trace('ZitiContext.ssl_connect() entered'); + // this.logger.trace('ZitiContext.ssl_connect() entered'); - let result = this._libCrypto.ssl_connect(ssl); + // let result = this._libCrypto.ssl_connect(ssl); - this.logger.trace('ZitiContext.ssl_connect() exiting'); + // this.logger.trace('ZitiContext.ssl_connect() exiting'); - return result; - } + // return result; + // } /** * */ - ssl_get_verify_result(ssl) { + // ssl_get_verify_result(ssl) { - this.logger.trace('ZitiContext.ssl_get_verify_result() entered'); + // this.logger.trace('ZitiContext.ssl_get_verify_result() entered'); - let result = this._libCrypto.ssl_get_verify_result(ssl); + // let result = this._libCrypto.ssl_get_verify_result(ssl); - this.logger.trace('ZitiContext.ssl_get_verify_result() exiting with: ', result); + // this.logger.trace('ZitiContext.ssl_get_verify_result() exiting with: ', result); - return result; + // return result; + + // } + /** + * + */ + async acquireTLSHandshakeLock(fd) { + this.logger.trace(`ZitiContext.acquireTLSHandshakeLock() [${fd}] trying to acquire _tlsHandshakeLock`); + this._tlsHandshakeLockRelease = await this._tlsHandshakeLock.acquire(); + this._tlsHandshakeLockFD = fd; + this.logger.trace(`ZitiContext.acquireTLSHandshakeLock() [${fd}] successfully acquired _tlsHandshakeLock`); + } + releaseTLSHandshakeLock(fd) { + if (isEqual(this._tlsHandshakeLockFD, fd)) { + this.logger.trace(`ZitiContext.releaseTLSHandshakeLock() [${fd}] releasing _tlsHandshakeLock`); + this._tlsHandshakeLockFD = undefined; + this._tlsHandshakeLockRelease(); + } } + /** * * @param {*} wasmFD // id of socket * @param {*} arrayBuffer // ArrayBuffer */ - async tls_enqueue(wasmFD, arrayBuffer) { + async tls_enqueue(wasmInstance, wasmFD, arrayBuffer) { this.logger.trace('ZitiContext.tls_enqueue(%d) [%o] entered', wasmFD, arrayBuffer); @@ -690,7 +760,7 @@ class ZitiContext extends EventEmitter { // const release = await lock.acquire(); // this.logger.trace('ZitiContext.tls_enqueue() acquired _lockByFD [%o]', wasmFD); - this._libCrypto.tls_enqueue(wasmFD, arrayBuffer); + this._libCrypto.tls_enqueue(wasmInstance, wasmFD, arrayBuffer); // this.logger.trace('ZitiContext.tls_enqueue() releasing _lockByFD [%o]', wasmFD); // release(); @@ -700,9 +770,9 @@ class ZitiContext extends EventEmitter { /** * */ - async tls_write(ssl, wireData) { + async tls_write(wasmInstance, ssl, wireData) { - this.logger.trace('ZitiContext.tls_write() entered'); + this.logger.trace('ZitiContext.tls_write() entered, ssl, wireData: ', ssl, wireData); // let lock = this._lockByFD.get( ssl ); // if (isUndefined(lock)) { @@ -714,7 +784,7 @@ class ZitiContext extends EventEmitter { // const release = await lock.acquire(); // this.logger.trace('ZitiContext.tls_write() acquired _lockByFD [%o]', ssl); - let result = this._libCrypto.tls_write(ssl, wireData); + let result = this._libCrypto.tls_write(wasmInstance, ssl, wireData); // this.logger.trace('ZitiContext.tls_write() releasing _lockByFD [%o]', ssl); // release(); @@ -727,7 +797,7 @@ class ZitiContext extends EventEmitter { /** * */ - tls_read(ssl) { + tls_read(wasmInstance, ssl) { this.logger.trace('ZitiContext.tls_read(%d) entered', ssl); @@ -741,7 +811,7 @@ class ZitiContext extends EventEmitter { // const release = await lock.acquire(); // this.logger.trace('ZitiContext.tls_read() acquired _lockByFD [%o]', ssl); - let result = this._libCrypto.tls_read(ssl); + let result = this._libCrypto.tls_read(wasmInstance, ssl); // this.logger.trace('ZitiContext.tls_read() releasing _lockByFD [%o]', ssl); // release(); @@ -882,10 +952,10 @@ class ZitiContext extends EventEmitter { /** * */ - async getCasPEM () { + async getCasPEM () { if (isNull(this._privateKeyPEM)) { - this._privateKeyPEM = this.getPrivateKeyPEM(this._pkey) + this._privateKeyPEM = await this.getPrivateKeyPEM(this._pkey) } if (isNull(this._certPEM)) { await this.enroll() @@ -900,7 +970,7 @@ class ZitiContext extends EventEmitter { async getCertPEM () { if (isNull(this._privateKeyPEM)) { - this._privateKeyPEM = this.getPrivateKeyPEM(this._pkey) + this._privateKeyPEM = await this.getPrivateKeyPEM(this._pkey) } if (isNull(this._certPEM)) { await this.enroll() @@ -915,7 +985,7 @@ class ZitiContext extends EventEmitter { async getCertPEMExpiryTime () { if (isNull(this._privateKeyPEM)) { - this._privateKeyPEM = this.getPrivateKeyPEM(this._pkey) + this._privateKeyPEM = await this.getPrivateKeyPEM(this._pkey) } if (isNull(this._certPEM)) { await this.enroll() @@ -1610,7 +1680,7 @@ class ZitiContext extends EventEmitter { let hostname = parsedURL.hostname; let port = parseInt(parsedURL.port, 10); - if (port === '') { + if ((port === '') || (parsedURL.port === '')) { if ((parsedURL.protocol === 'https:') || (parsedURL.protocol === 'wss:')) { port = 443; } else { diff --git a/src/enroll/enroller.js b/src/enroll/enroller.js index 0685176..a2c7e8a 100644 --- a/src/enroll/enroller.js +++ b/src/enroll/enroller.js @@ -42,7 +42,7 @@ import { isUndefined, isNull } from 'lodash-es'; let _options = flatOptions(options, defaultOptions); - this.zitiContext = _options.zitiContext; + this._zitiContext = _options.zitiContext; this.logger = _options.logger; } @@ -64,14 +64,14 @@ import { isUndefined, isNull } from 'lodash-es'; async enroll() { // Don't proceed until we have successfully logged in to Controller and have established an API session - let token = await this.zitiContext.ensureAPISession(); + let token = await this._zitiContext.ensureAPISession(); if (isUndefined(token) || isNull(token)) { this.logger.trace('ZitiEnroller.enroll(): ensureAPISession returned null'); return false; } - this.generateCSR(); + await this.generateCSR( await this._zitiContext.getInstance_OuterWASM() ); let result = await this.createEphemeralCert(); @@ -82,10 +82,12 @@ import { isUndefined, isNull } from 'lodash-es'; /** * */ - generateCSR() { + async generateCSR(wasmInstance) { - this._csr = this.zitiContext.createCertificateSigningRequest({ - key: this.zitiContext.pKey, + let pKey = await this._zitiContext.get_pKey(); + + this._csr = this._zitiContext.createCertificateSigningRequest(wasmInstance, { + key: pKey, }) } @@ -96,7 +98,7 @@ import { isUndefined, isNull } from 'lodash-es'; */ async createEphemeralCert() { - let res = await this.zitiContext._zitiBrowzerEdgeClient.createCurrentApiSessionCertificate({ + let res = await this._zitiContext._zitiBrowzerEdgeClient.createCurrentApiSessionCertificate({ sessionCertificate: { csr: this._csr } diff --git a/src/http/_http_client.js b/src/http/_http_client.js index 2cca7ae..2bc7d2c 100644 --- a/src/http/_http_client.js +++ b/src/http/_http_client.js @@ -692,7 +692,7 @@ function tickOnSocket(req, socket) { parser.outgoing = req; req.parser = parser; - socket.parser = parser; + socket.parser = req.parser; socket._httpMessage = req; // Propagate headers limit from request object to parser diff --git a/src/http/readable-stream/_stream_readable.js b/src/http/readable-stream/_stream_readable.js index b287636..2e20dda 100644 --- a/src/http/readable-stream/_stream_readable.js +++ b/src/http/readable-stream/_stream_readable.js @@ -634,7 +634,12 @@ class Readable extends Stream { if (nOrig !== n && state.ended) endReadable(this); } - if (ret !== null) this.emit('data', ret); + if (ret !== null) { + this.emit('data', ret); + } + if (ret === null) { + // this.emit('end'); + } return ret; }; diff --git a/src/http/ziti-agent.js b/src/http/ziti-agent.js index d90f14c..41f8d7b 100644 --- a/src/http/ziti-agent.js +++ b/src/http/ziti-agent.js @@ -136,7 +136,6 @@ ZitiAgent.prototype.createConnection = async function(opts, deferredFn) { let innerTLSSocket = new ZitiInnerTLSSocket( this.proxy ); innerTLSSocket.setWASMFD(this.proxy.zitiContext.addWASMFD(innerTLSSocket)); innerTLSSocket.setOuterSocket(this.socket); - await innerTLSSocket.pullKeyPair(); this.socket.innerTLSSocket = innerTLSSocket; await innerTLSSocket.create(); innerTLSSocket.on('data', innerTLSSocketOnData); diff --git a/src/http/ziti-inner-tls-socket.js b/src/http/ziti-inner-tls-socket.js index 5b2f948..e7e8539 100644 --- a/src/http/ziti-inner-tls-socket.js +++ b/src/http/ziti-inner-tls-socket.js @@ -17,67 +17,67 @@ limitations under the License. import EventEmitter from 'events'; import { isUndefined, isNull } from 'lodash-es'; import {Mutex, withTimeout} from 'async-mutex'; -import { Buffer } from 'buffer/'; // note: the trailing slash is important! - -class Queue { - constructor(logger) { - this.logger = logger; - this.elements = {}; - this.head = 0; - this.tail = 0; - this.mutex = withTimeout(new Mutex(), 1 * 1000, new Error('timeout on Queue mutex')); - } - async enqueue(element) { - this.logger.trace(`Queue.enqueue() entered: `, element); - await this.mutex.runExclusive( () => { - this.elements[this.tail] = element; - this.tail++; - }); - this.logger.trace(`Queue.enqueue() exiting: `, element); - } - async dequeue() { - this.logger.trace(`Queue.dequeue() entered`); - let item; - await this.mutex.runExclusive( () => { - item = this.elements[this.head]; - delete this.elements[this.head]; - this.head++; - }); - this.logger.trace(`Queue.dequeue() exiting: `, item); - return item; - } - peek() { - return this.elements[this.head]; - } - headNdx() { - return this.head; - } - peekNdx(ndx) { - return this.elements[ndx]; - } - async acquireMutex() { - this.logger.trace(`Queue.acquireMutex() waiting for mutex`); - const release = await this.mutex.acquire(); - this.logger.trace(`Queue.acquireMutex() now own mutex`); - return release; - } - get length() { - return this.tail - this.head; - } - get isEmpty() { - return this.length === 0; - } -} +// import { Buffer } from 'buffer/'; // note: the trailing slash is important! + +// class Queue { +// constructor(logger) { +// this.logger = logger; +// this.elements = {}; +// this.head = 0; +// this.tail = 0; +// this.mutex = withTimeout(new Mutex(), 1 * 1000, new Error('timeout on Queue mutex')); +// } +// async enqueue(element) { +// this.logger.trace(`Queue.enqueue() entered: `, element); +// await this.mutex.runExclusive( () => { +// this.elements[this.tail] = element; +// this.tail++; +// }); +// this.logger.trace(`Queue.enqueue() exiting: `, element); +// } +// async dequeue() { +// this.logger.trace(`Queue.dequeue() entered`); +// let item; +// await this.mutex.runExclusive( () => { +// item = this.elements[this.head]; +// delete this.elements[this.head]; +// this.head++; +// }); +// this.logger.trace(`Queue.dequeue() exiting: `, item); +// return item; +// } +// peek() { +// return this.elements[this.head]; +// } +// headNdx() { +// return this.head; +// } +// peekNdx(ndx) { +// return this.elements[ndx]; +// } +// async acquireMutex() { +// this.logger.trace(`Queue.acquireMutex() waiting for mutex`); +// const release = await this.mutex.acquire(); +// this.logger.trace(`Queue.acquireMutex() now own mutex`); +// return release; +// } +// get length() { +// return this.tail - this.head; +// } +// get isEmpty() { +// return this.length === 0; +// } +// } class ZitiInnerTLSSocket extends EventEmitter { constructor(opts) { super(); - this._connected_cb = null; + // this._connected_cb = null; this._connected = false; - this._read_cb = null; + // this._read_cb = null; this._datacb = opts.datacb; @@ -132,7 +132,7 @@ class ZitiInnerTLSSocket extends EventEmitter { this._reader = this._readable.getReader(); this._writer = this._writable.getWriter(); this._readerBuffer = null; - this._q = new Queue(this._zitiContext.logger); + // this._q = new Queue(this._zitiContext.logger); this._fd_read_depth = 0; @@ -170,7 +170,7 @@ class ZitiInnerTLSSocket extends EventEmitter { */ async pullKeyPair() { - this._privateKeyPEM = this._zitiContext.privateKeyPEM; + this._privateKeyPEM = this._zitiContext.get_privateKeyPEM(); this._certPEM = await this._zitiContext.getCertPEM(); @@ -189,19 +189,27 @@ class ZitiInnerTLSSocket extends EventEmitter { */ async create() { - this._sslContext = await this._zitiContext.ssl_CTX_new(); + this._wasmInstance = await this._zitiContext.getInstance_InnerWASM(); + + this._sslContext = await this._zitiContext.ssl_CTX_new( this._wasmInstance ); - this._BIO = this._zitiContext.bio_new_ssl_connect(this._sslContext); + this._BIO = this._zitiContext.bio_new_ssl_connect(this._wasmInstance, this._sslContext); - this._SSL = this._zitiContext.bio_get_ssl(this._BIO); + this._SSL = this._zitiContext.bio_get_ssl(this._wasmInstance, this._BIO); // Tie the WASM-based SSL object back to this ZitiInnerTLSSocket so that later when // the low-level WASM code does fd-level i/o, our WASM-JS will intercept it, and // interface with this socket, so we can route traffic over our outer ZitiSocket, and // then on to the ER. - this._zitiContext.ssl_set_fd( this._SSL, this.getWASMFD() ); + this._zitiContext.ssl_set_fd( this._wasmInstance, this._SSL, this.getWASMFD() ); + self._zitiContext.logger.trace('ZitiInnerTLSSocket.create() wasmFD[%d] starting TLS handshake', this.getWASMFD()); + + this.handshake(); + await this.awaitTLSHandshakeComplete(); + + self._zitiContext.logger.trace('ZitiInnerTLSSocket.create() wasmFD[%d] TLS handshake completed', this.getWASMFD()); } @@ -213,8 +221,8 @@ class ZitiInnerTLSSocket extends EventEmitter { let self = this; return new Promise((resolve) => { (function waitForTLSHandshakeComplete() { - if (!self._connected) { - self._zitiContext.logger.trace('ZitiInnerTLSSocket.awaitTLSHandshakeComplete() wasmFD[%d] TLS handshake still not complete', self.wasmFD); + if (!self.connected) { + // self._zitiContext.logger.trace('ZitiInnerTLSSocket.awaitTLSHandshakeComplete() wasmFD[%d] TLS handshake still not complete', self.wasmFD); setTimeout(waitForTLSHandshakeComplete, 10); } else { self._zitiContext.logger.trace('ZitiInnerTLSSocket.awaitTLSHandshakeComplete() wasmFD[%d] TLS handshake complete', self.wasmFD); @@ -228,67 +236,92 @@ class ZitiInnerTLSSocket extends EventEmitter { /** * */ - handshake_cb(self, rc) { - self._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake_cb(): entered rc=%d ', rc ); + // handshake_cb(self, rc) { + // self._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake_cb(): entered rc=%d ', rc ); - if (rc < 0) { - throw new Error(`TLS handshake failed for fd[${self.wasmFD}]`); - } + // if (rc < 0) { + // throw new Error(`TLS handshake failed for fd[${self.wasmFD}]`); + // } - // Let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, - // before we turn loose any writes to the connection - setTimeout((tlsConn, rc) => { - self._zitiContext.logger.trace("ZitiInnerTLSSocket.handshake_cb(): after timeout"); - self._connected = true; - }, 5, self, rc) + // // Let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, + // // before we turn loose any writes to the connection + // setTimeout((tlsConn, rc) => { + // self._zitiContext.logger.trace("ZitiInnerTLSSocket.handshake_cb(): after timeout"); + // self._connected = true; + // }, 5, self, rc) + // } + + /** + * + */ + async handshake() { + await this._zitiContext.acquireTLSHandshakeLock( this.wasmFD ); + this._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake(): fd[%d] calling ssl_do_handshake()', this.wasmFD ); + let result = this._zitiContext.ssl_do_handshake( this._wasmInstance, this._SSL ); + this._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake(): fd[%d] back from ssl_do_handshake(): result=%d (now awaiting cb)', this.wasmFD, result ); } /** * */ - handshake() { + get connected() { - // Make sure WASM knows where to callback to once handshake is complete - this._connected_cb = this.handshake_cb; + // If we already did the work, and are fully connected, take a quick exit + if (this._connected) return true; - this._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake(): fd[%d] calling ssl_do_handshake()', this.wasmFD ); - let result = this._zitiContext.ssl_do_handshake( this._SSL ); - this._zitiContext.logger.trace('ZitiInnerTLSSocket.handshake(): fd[%d] back from ssl_do_handshake() for %o: result=%d (now awaiting cb)', this.wasmFD, this._id, result ); + // Ask the SSL if its handshake has completed yet + let _connected = this._zitiContext.ssl_is_init_finished(this._wasmInstance, this._SSL); + + // If SSL indicates handshake has completed, let's delay a smidge, and allow the WASM mTLS ciphersuite-exchange to complete, + // before we turn loose any writes to the connection + if (_connected) { + + setTimeout((self) => { + self._zitiContext.logger.trace('ZitiInnerTLSSocket.connected(): fd[%d] after timeout', this.wasmFD); + self._connected = true; + self._zitiContext.releaseTLSHandshakeLock( this.wasmFD ); + }, 200, this); + + } + + return this._connected } /** * */ - captureResponseData(conn, data) { + // async captureResponseData(conn, data) { - conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() <- conn[%d], dataLen: [%o]", conn.id, data.byteLength); - conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() <- conn[%d], (string)data: [%s]", conn.id, Buffer.from(data, 'utf8')); + // conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() <- conn[%d], dataLen: [%o]", conn.id, data.byteLength); + // conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() <- conn[%d], (string)data: [%s]", conn.id, Buffer.from(data, 'utf8')); - let zitiSocket = conn.socket; - let self = zitiSocket.innerTLSSocket; + // let zitiSocket = conn.socket; + // let self = zitiSocket.innerTLSSocket; - if (data.byteLength > 0) { + // if (data.byteLength > 0) { - // Push it into the stream that is read by fd_read - // self._readableZitiStreamController.enqueue( new Uint8Array(data, 0) ); - self._writer.write( new Uint8Array(data, 0) ); + // // Push it into the stream that is read by fd_read + // // self._readableZitiStreamController.enqueue( new Uint8Array(data, 0) ); + // self._writer.write( new Uint8Array(data, 0) ); - // If the TLS handshake has completed, we'll need to do TLS-decrypt of the data, - // and then propagate it to the Promise that is waiting for it. - if (self._connected) { + // // If the TLS handshake has completed, we'll need to do TLS-decrypt of the data, + // // and then propagate it to the Promise that is waiting for it. + // if (self._connected) { - conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() handshake previously completed [%d]", conn.id); + // conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() handshake previously completed [%d]", conn.id); - // Make sure WASM knows where to callback to once data is ready - self._read_cb = self.read_cb; + // // Make sure WASM knows where to callback to once data is ready + // self._read_cb = self.read_cb; - self._zitiContext.tls_read(self._SSL); // TLS-decrypt some data from the queue + // let wasmInstance = await this._zitiContext.getInstance_InnerWASM(); - } else { - conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() handshake not yet completed [%d]", conn.id); - } - } - } + // self._zitiContext.tls_read(wasmInstance, self._SSL); // TLS-decrypt some data from the queue + + // } else { + // conn._zitiContext.logger.trace("ZitiInnerTLSSocket.captureResponseData() handshake not yet completed [%d]", conn.id); + // } + // } + // } /** * @@ -307,9 +340,9 @@ class ZitiInnerTLSSocket extends EventEmitter { * * @param {*} wireData (not TLS-encrypted yet) */ - tls_write(wireData) { + async tls_write(wireData) { this._zitiContext.logger.trace(`ZitiInnerTLSSocket.tls_write[${this.wasmFD}] unencrypted data is ready to be sent to the ER ---> [%o]`, wireData); - this._zitiContext.tls_write(this._SSL, wireData); + this._zitiContext.tls_write(this._wasmInstance, this._SSL, wireData); } /** @@ -321,7 +354,7 @@ class ZitiInnerTLSSocket extends EventEmitter { async fd_write(wireData) { // this._zitiContext.logger.trace(`ZitiInnerTLSSocket.fd_write[${this.wasmFD}]: encrypted data is ready`); const conn = await this.outerSocket.getZitiConnection(); - if (!this._connected) { + if (!this.connected) { // this._zitiContext.logger.trace(`ZitiInnerTLSSocket.fd_write[${this.wasmFD}]: (handshake data) is being sent to ch[${conn.channel.id}] --->`); conn.channel.write(conn, wireData); } else { @@ -341,7 +374,7 @@ class ZitiInnerTLSSocket extends EventEmitter { async write(conn, buffer) { // Complete the TLS handshake if necessary - if (!this._connected) { + if (!this.connected) { this.handshake(); await this.awaitTLSHandshakeComplete(); } @@ -379,132 +412,132 @@ class ZitiInnerTLSSocket extends EventEmitter { // return srcBuffer.copy( targetBuffer, targetStart, this._readerBufferOffset, (this._readerBufferOffset + targetLength) ); // } - async _getQueueLength() { + // async _getQueueLength() { - let release = await this._q.acquireMutex(); + // let release = await this._q.acquireMutex(); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP -VVV------------------------------------`); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP -VVV------------------------------------`); - let dumpctr = 0; - for (const [key, value] of Object.entries(this._q.elements)) { - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP `, key, value); - dumpctr += value.byteLength - value.offset; - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP `, (value.byteLength - value.offset), dumpctr); - } - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP -^^^------------------------------------`, dumpctr); + // let dumpctr = 0; + // for (const [key, value] of Object.entries(this._q.elements)) { + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP `, key, value); + // dumpctr += value.byteLength - value.offset; + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP `, (value.byteLength - value.offset), dumpctr); + // } + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: DUMP -^^^------------------------------------`, dumpctr); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: releasing mutex`); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._getQueueLength[${this.wasmFD}]: releasing mutex`); - release(); + // release(); - return dumpctr; - } + // return dumpctr; + // } - async _awaitTargetLengthPresent(targetLength) { + // async _awaitTargetLengthPresent(targetLength) { - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: entered for targetLength[${targetLength}]`); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: entered for targetLength[${targetLength}]`); - let totalLen = await this._getQueueLength(); + // let totalLen = await this._getQueueLength(); - while (totalLen < targetLength) { + // while (totalLen < targetLength) { - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: awaiting on _reader.read()`); - const { value: view, done } = await this._reader.read(); - let chunk = { - offset: 0, - byteLength: view.buffer.byteLength, - buffer: view.buffer - } - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: returned from this._reader.read(), enqueueing new chunk of byteLength[${chunk.byteLength}]`); - await this._q.enqueue( chunk ); - - totalLen = await this._getQueueLength(); - } - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: returning totalLen[${totalLen}]`); - - return totalLen; - } - - async _readInto(targetBuffer) { - - let remainingTargetLength = targetBuffer.byteLength; - let targetBufferOffset = 0; - targetBuffer = new Buffer(targetBuffer); - - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: entered, targetLength[${targetBuffer.byteLength}]`); - - // Do not proceed until the queue is populated with enough data to fulfill the read request - let totalLen = await this._awaitTargetLengthPresent(remainingTargetLength); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: totalLen in this._q is: `, totalLen); - - while (remainingTargetLength > 0) { // Until all requested bytes have been delivered - - let chunk = this._q.peek(); // Get top-most chunk, and determine unconsumed portion + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: awaiting on _reader.read()`); + // const { value: view, done } = await this._reader.read(); + // let chunk = { + // offset: 0, + // byteLength: view.buffer.byteLength, + // buffer: view.buffer + // } + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: returned from this._reader.read(), enqueueing new chunk of byteLength[${chunk.byteLength}]`); + // await this._q.enqueue( chunk ); + + // totalLen = await this._getQueueLength(); + // } + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._awaitTargetLengthPresent[${this.wasmFD}]: returning totalLen[${totalLen}]`); - if (isUndefined(chunk)) { - debugger - } + // return totalLen; + // } - let remainingChunkLen = (chunk.byteLength - chunk.offset); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: remainingTargetLength[${remainingTargetLength}] remainingChunkLen[${remainingChunkLen}]`); + // async _readInto(targetBuffer) { - let srcBuffer = new Buffer(chunk.buffer); + // let remainingTargetLength = targetBuffer.byteLength; + // let targetBufferOffset = 0; + // targetBuffer = new Buffer(targetBuffer); - if (remainingChunkLen < remainingTargetLength) { // if chunk is too small to completely fulfill read request, then - // consume remaining contents of this chunk, then dispose of it - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 1 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); - let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingChunkLen)); - remainingTargetLength -= bytesCopied; - targetBufferOffset += bytesCopied; - chunk.offset += bytesCopied; - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 1 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}] purging chunk`); - await this._q.dequeue(); - } - else if (remainingChunkLen == remainingTargetLength) { // if chunk will exactly fulfill read request, then - // consume remaining contents of this chunk, then dispose of it - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 2 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); - let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingChunkLen)); - remainingTargetLength -= bytesCopied; - chunk.offset += bytesCopied; - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 2 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}] purging chunk`); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: this._q before: `, this._q); - await this._q.dequeue(); - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: this._q after: `, this._q); - } else { // Chunk contains more than enough data to fulfill read request, so - // consume leading fragment of this chunk, update its offset, and leave it in the queue - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 3 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); - let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingTargetLength)); - remainingTargetLength -= bytesCopied; - chunk.offset += bytesCopied; - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 3 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}]`); - } + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: entered, targetLength[${targetBuffer.byteLength}]`); + + // // Do not proceed until the queue is populated with enough data to fulfill the read request + // let totalLen = await this._awaitTargetLengthPresent(remainingTargetLength); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: totalLen in this._q is: `, totalLen); + + // while (remainingTargetLength > 0) { // Until all requested bytes have been delivered + + // let chunk = this._q.peek(); // Get top-most chunk, and determine unconsumed portion + + // if (isUndefined(chunk)) { + // debugger + // } + + // let remainingChunkLen = (chunk.byteLength - chunk.offset); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: remainingTargetLength[${remainingTargetLength}] remainingChunkLen[${remainingChunkLen}]`); + + // let srcBuffer = new Buffer(chunk.buffer); + + // if (remainingChunkLen < remainingTargetLength) { // if chunk is too small to completely fulfill read request, then + // // consume remaining contents of this chunk, then dispose of it + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 1 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); + // let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingChunkLen)); + // remainingTargetLength -= bytesCopied; + // targetBufferOffset += bytesCopied; + // chunk.offset += bytesCopied; + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 1 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}] purging chunk`); + // await this._q.dequeue(); + // } + // else if (remainingChunkLen == remainingTargetLength) { // if chunk will exactly fulfill read request, then + // // consume remaining contents of this chunk, then dispose of it + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 2 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); + // let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingChunkLen)); + // remainingTargetLength -= bytesCopied; + // chunk.offset += bytesCopied; + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 2 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}] purging chunk`); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: this._q before: `, this._q); + // await this._q.dequeue(); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: this._q after: `, this._q); + // } else { // Chunk contains more than enough data to fulfill read request, so + // // consume leading fragment of this chunk, update its offset, and leave it in the queue + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 3 copying at targetBufferOffset[${targetBufferOffset}] chunk.offset[${chunk.offset}]`); + // let bytesCopied = srcBuffer.copy( targetBuffer, targetBufferOffset, chunk.offset, (chunk.offset+remainingTargetLength)); + // remainingTargetLength -= bytesCopied; + // chunk.offset += bytesCopied; + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: 3 bytesCopied[${bytesCopied}] remainingChunkLen[${(chunk.byteLength - chunk.offset)}]`); + // } - } + // } - this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: exiting`); + // this._zitiContext.logger.trace(`ZitiInnerTLSSocket._readInto[${this.wasmFD}]: exiting`); - return targetBuffer.buffer; - } + // return targetBuffer.buffer; + // } /** * */ - read_cb(self, buffer) { - self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): clear data from outer socket is ready <--- [%o]', buffer); - // If WASM passed an undefined buffer it means that there was a zero-length read from the socket - if (isUndefined(buffer)) { - console.log('ZitiInnerTLSSocket.read_cb(): emitting "close"'); - self.emit('close', buffer); - } - // // Otherwise, emit the data to the listener - else { - // // self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): clear data from outer socket is ready <--- [%o]', buffer); - self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): emitting "data" from outer socket <--- [%s]', String.fromCharCode.apply(null, new Uint8Array(buffer))); - self.emit('data', buffer); - } - // this._tlsProcessLockRelease(); - } + // read_cb(self, buffer) { + // self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): clear data from outer socket is ready <--- [%o]', buffer); + // // If WASM passed an undefined buffer it means that there was a zero-length read from the socket + // if (isUndefined(buffer)) { + // console.log('ZitiInnerTLSSocket.read_cb(): emitting "close"'); + // self.emit('close', buffer); + // } + // // // Otherwise, emit the data to the listener + // else { + // // // self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): clear data from outer socket is ready <--- [%o]', buffer); + // self._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): emitting "data" from outer socket <--- [%s]', String.fromCharCode.apply(null, new Uint8Array(buffer))); + // self.emit('data', buffer); + // } + // // this._tlsProcessLockRelease(); + // } /** @@ -517,7 +550,7 @@ class ZitiInnerTLSSocket extends EventEmitter { if (arrayBuffer.byteLength === 0) { // If the TLS handshake has completed, and we get a zero-length buffer... - if (this._connected) { + if (this.connected) { // ...then emit the 'close' event this._zitiContext.logger.trace("ZitiInnerTLSSocket.process() fd[%d] emitting 'close' event", this.wasmFD); this.emit('close', undefined); @@ -525,19 +558,19 @@ class ZitiInnerTLSSocket extends EventEmitter { } else { - await this._zitiContext.tls_enqueue(this.wasmFD, arrayBuffer); // enqueue the encrypted data + await this._zitiContext.tls_enqueue(this._wasmInstance, this.wasmFD, arrayBuffer); // enqueue the encrypted data // If the TLS handshake has completed, we'll need to do TLS-decrypt of the data, // and then propagate it to the Promise that is waiting for it. - if (this._connected) { + if (this.connected) { // Make sure WASM knows where to callback to once data is ready // this._read_cb = this.read_cb; - let decryptedData = this._zitiContext.tls_read(this._SSL); // TLS-decrypt some data from the queue + let decryptedData = this._zitiContext.tls_read(this._wasmInstance, this._SSL); // TLS-decrypt some data from the queue this._zitiContext.logger.trace('ZitiInnerTLSSocket.process[%d]: clear data from the outer socket is ready <--- len[%d]', this.wasmFD, decryptedData.byteLength); - this._zitiContext.logger.trace('ZitiInnerTLSSocket.read_cb(): emitting "data" from outer socket <--- [%s]', String.fromCharCode.apply(null, new Uint8Array(decryptedData))); + this._zitiContext.logger.trace('ZitiInnerTLSSocket.process(): emitting "data" from outer socket <--- [%s]', String.fromCharCode.apply(null, new Uint8Array(decryptedData))); this.emit('data', decryptedData.buffer); } } diff --git a/src/http/ziti-xhr.js b/src/http/ziti-xhr.js index ff80358..e3b8395 100644 --- a/src/http/ziti-xhr.js +++ b/src/http/ziti-xhr.js @@ -286,6 +286,7 @@ function ZitiXMLZitiHttpRequest () { self.responseBodyText = await blob.text(); self.responseText = self.responseBodyText; self.response = self.responseBodyText; + self.responseXML = self.responseBodyText; sendFlag = false; setState(self.DONE); }); diff --git a/src/reporters/zitiReporter.js b/src/reporters/zitiReporter.js index 2800226..cfa7881 100644 --- a/src/reporters/zitiReporter.js +++ b/src/reporters/zitiReporter.js @@ -71,7 +71,7 @@ export default class ZitiReporter { const style = logObj.type === 'success' ? successStyle : normalStyle - const badge = logObj.type === 'success' ? `%cZiti` : `%cZiti${suffix}-${[tag, type].filter(Boolean).join(':')}` + const badge = logObj.type === 'success' ? `%cZiti` : `%c${suffix}-${[tag, type].filter(Boolean).join(':')}` // Log to the console if (typeof logObj.args[0] === 'string') { diff --git a/src/ziti-browzer-core.js b/src/ziti-browzer-core.js index b8be830..f259267 100644 --- a/src/ziti-browzer-core.js +++ b/src/ziti-browzer-core.js @@ -36,7 +36,9 @@ class ZitiBrowzerCore { */ createZitiContext (options) { - if (this._zitiContext !== undefined) throw Error("Already have a ZitiContext; Cannot call .createZitiContext() twice on instance."); + if (this._zitiContext !== undefined) { + throw Error("Already have a ZitiContext; Cannot call .createZitiContext() twice on instance."); + } this._zitiContext = new ZitiContext(Object.assign({ logger: options.logger, @@ -58,9 +60,6 @@ class ZitiBrowzerCore { } get context () { - if (this._zitiContext === undefined) { - this._zitiContext = new ZitiContext(); - } return this._zitiContext; } diff --git a/yarn.lock b/yarn.lock index 23ec4b0..a375df3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1032,10 +1032,10 @@ portfinder "^1.0.21" request "^2.88.0" -"@openziti/libcrypto-js@^0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@openziti/libcrypto-js/-/libcrypto-js-0.14.1.tgz#bf5a0fa4be7d72bcf0129c3f7bb2f0af61f2aa46" - integrity sha512-C0otRXXspn++wlGXGFSCGibafm0go97g4QoWoc3nLY92uw5UlKB3zs/8pP1xtpWoosukyqOCh65zhhYhSPrEtA== +"@openziti/libcrypto-js@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@openziti/libcrypto-js/-/libcrypto-js-0.15.0.tgz#48bdbf98af9bb90d743958f53562e2eaf894bfa7" + integrity sha512-/IsnCWoLYckL8/5EmWd1B/cj5egxrjLxOPTtDMwJVxvACumcWFWvVNzg6z4XvwHsNUd6m4JDtQFO3HTwAvDAuQ== dependencies: "@types/emscripten" "^1.39.6" "@wasmer/wasi" "^1.0.2"