This demonstrate the issue with Electron v4 during TLS renegotiation.
Electron v3
- electron/node ships with OpenSSL
- OpenSSL enables TLS renegotiation by default
Electron v4
- Both Node.js & Chromium uses BoringSSL
- Renegotiation is disabled in BoringSSL by default
However, Chromium configured BoringSSL to allow renegotiations using:
SSL_set_renegotiate_mode(ssl_.get(), ssl_renegotiate_freely);
But, its not patched in electron/node
and there's no API to configure this on runtime as well.
Which means TLS renegotiation is disabled on the main process.
- Open Issue: electron/electron#18380
- On renegotiation, client request via main process fails because of
socket hang up
- Local server running on the main process fails to initiate renegotiate request
$ git clone https://github.com/codenirvana/electron-tls-renegotiation.git
$ npm install # install dependencies
$ npm run test-v3 # test with Electron v3
$ npm run test-v4 # test with Electron v4
$ npm run server # test and run a local server
- renegotiation on Node.js
- renegotiation on Electron's main process (https.request)
- renegotiation on Electron's renderer process (BrowserWindow~loadUrl)
Node.js
$ npm run server
< server listening at: https://localhost:5050
TEST: https.request - Node.js
> request socket connect
> request socket secureConnect
> request socket authorized false
> request socket authorizationError SELF_SIGNED_CERT_IN_CHAIN
> request socket protocol: TLSv1.2
> request socket cipher: {"name":"ECDHE-RSA-AES128-GCM-SHA256","version":"TLSv1/SSLv3"}
< incoming request at: /
< renegotiating: true
> request socket secureConnect
> request socket authorized false
> request socket authorizationError SELF_SIGNED_CERT_IN_CHAIN
> request socket protocol: TLSv1.2
> request socket cipher: {"name":"ECDHE-RSA-AES128-GCM-SHA256","version":"TLSv1/SSLv3"}
< renegotiated peer certificate: {}
> request status: 200
> response chunk: -- Renegotiated --
Electron v3
$ npm run test-v3
TEST: https.request - main process
> request socket connect
> request socket secureConnect
> request socket authorized false
> request socket authorizationError SELF_SIGNED_CERT_IN_CHAIN
> request socket protocol: TLSv1.2
> request socket cipher: {"name":"ECDHE-RSA-AES128-GCM-SHA256","version":"TLSv1/SSLv3"}
< incoming request at: /
< renegotiating: true
> request socket secureConnect
> request socket authorized false
> request socket authorizationError SELF_SIGNED_CERT_IN_CHAIN
> request socket protocol: TLSv1.2
> request socket cipher: {"name":"ECDHE-RSA-AES128-GCM-SHA256","version":"TLSv1/SSLv3"}
< renegotiated peer certificate: {}
> request status: 200
> response chunk: -- Renegotiated --
TEST: BrowserWindow~loadURL - renderer process
< incoming request at: /
< renegotiating: true
< renegotiated peer certificate: {}
Electron v4
$ npm run test-v4
TEST: https.request - main process
> request socket connect
> request socket secureConnect
> request socket authorized false
> request socket authorizationError SELF_SIGNED_CERT_IN_CHAIN
> request socket protocol: TLSv1.2
> request socket cipher: {"name":"ECDHE-RSA-AES128-GCM-SHA256","version":"TLSv1/SSLv3"}
< incoming request at: /
< renegotiating: true
> request error: socket hang up
> request socket _tlsError: [Error: 140400950314152:error:100000b6:SSL routines:OPENSSL_internal:NO_RENEGOTIATION:../../third_party/boringssl/src/ssl/ssl_lib.cc:966:
]
> request error: 140400950314152:error:100000b6:SSL routines:OPENSSL_internal:NO_RENEGOTIATION:../../third_party/boringssl/src/ssl/ssl_lib.cc:966:
> request socket error: [Error: 140400950314152:error:100000b6:SSL routines:OPENSSL_internal:NO_RENEGOTIATION:../../third_party/boringssl/src/ssl/ssl_lib.cc:966:
]
TEST: BrowserWindow~loadURL - renderer process
< incoming request at: /
< renegotiating: true
< renegotiated peer certificate: {}
Renderer Process: Renegotiation works on both v3 and v4.
Main Process:
socket hang up
on v4, error log:
> request error: socket hang up
> request error: 140552750683976:error:100000b6:SSL routines:OPENSSL_internal:NO_RENEGOTIATION:../../third_party/boringssl/src/ssl/ssl_lib.cc:966:
Electron | Chromium | Node.js | Renegotiation (renderer) | Renegotiation (main) |
---|---|---|---|---|
v3 | BoringSSL | OpenSSL | ✅ | ✅ |
v4 | BoringSSL | BoringSSL | ✅ | ❌ |