@gjsify/tls 0.24.2 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/esm/connect.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{hasTlsSessionAccess as e}from"./session-access.js";import{TLSSocket as t}from"./tls-socket.js";import{createSecureContext as n}from"./secure-context.js";import r from"@girs/gio-2.0";import i from"@girs/glib-2.0";function connect(a,o){let s=new t(void 0,a);o&&s.once(`secureConnect`,o);let c=a.port||443,l=a.host||`localhost`,u=a.servername||l,d=a.rejectUnauthorized!==!1,f=a.secureContext??n(a);s._secureContext=f,s.servername=u;let p=a.checkServerIdentity;return s.once(`connect`,()=>{let t=s._connection;if(!t){s.destroy(Error(`No underlying connection for TLS upgrade`));return}try{let n=r.NetworkAddress.new(u,c),o=r.TlsClientConnection.new(t,n);if(o.set_server_identity(n),a.session&&e())try{s._tlsConnection=o,s.setSession(a.session)}catch{}if(f.certificate)try{o.set_certificate(f.certificate)}catch(e){console.warn(`[tls] failed to set client certificate:`,e)}
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{hasTlsSessionAccess as e}from"./session-access.js";import{TLSSocket as t}from"./tls-socket.js";import{createSecureContext as n}from"./secure-context.js";import r from"@girs/gio-2.0";import i from"@girs/glib-2.0";function connect(a,o){let s=new t(void 0,a);o&&s.once(`secureConnect`,o);let c=a.port||443,l=a.host||`localhost`,u=a.servername||l,d=a.rejectUnauthorized!==!1,f=a.secureContext??n(a);s._secureContext=f,s.servername=u;let p=a.checkServerIdentity;return s.once(`connect`,()=>{let t=s._connection;if(!t){s.destroy(Error(`No underlying connection for TLS upgrade`));return}try{let n=r.NetworkAddress.new(u,c),o=r.TlsClientConnection.new(t,n);if(o.set_server_identity(n),a.session&&e())try{s._tlsConnection=o,s.setSession(a.session)}catch{}if(f.certificate)try{o.set_certificate(f.certificate)}catch(e){console.warn(`[tls] failed to set client certificate:`,e)}a.ALPNProtocols&&a.ALPNProtocols.length>0&&o.set_advertised_protocols(a.ALPNProtocols),o.connect(`accept-certificate`,(e,t,i)=>{if(!d)return!0;if(f.caCertificates.length===0)return!1;for(let e of f.caCertificates)try{if(t.verify(n,e)===r.TlsCertificateFlags.NO_FLAGS)return!0}catch{}return!1});let l=new r.Cancellable;o.handshake_async(i.PRIORITY_DEFAULT,l,(t,n)=>{try{if(o.handshake_finish(n),s.authorized=!0,s._setupTlsStreams(o),s.alpnProtocol=s.getAlpnProtocol(),p){let e=s.getPeerCertificate(),t=p(u,e);if(t&&(s.authorized=!1,s.authorizationError=t.message,d)){s.destroy(t);return}}let t=s;if(t._reading=!1,t._startReading(),e()){let e=s.getSession();e&&s.emit(`session`,e)}s.emit(`secureConnect`)}catch(e){s.authorized=!1,s.authorizationError=e instanceof Error?e.message:String(e),d?s.destroy(e instanceof Error?e:Error(String(e))):(s._setupTlsStreams(o),s.emit(`secureConnect`))}})}catch(e){s.destroy(e instanceof Error?e:Error(String(e)))}}),s.connect({port:c,host:l}),s}export{connect};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{pemToDer as e}from"./pem.js";import t from"@girs/glib-2.0";function parseDistinguishedName(e){if(!e)return{};let t={};for(let n of e.split(/,(?![^=]*=)/)){let e=n.indexOf(`=`);if(e<0)continue;let r=n.slice(0,e).trim(),i=n.slice(e+1).trim(),a=t[r];a===void 0?t[r]=i:Array.isArray(a)?a.push(i):t[r]=[a,i]}return t}function formatCertDate(e){if(!e)return``;try{return e.format(`%b %d %H:%M:%S %Y GMT`)??``}catch{return``}}function formatAltNames(e){let t=[]
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{pemToDer as e}from"./pem.js";import t from"@girs/glib-2.0";function parseDistinguishedName(e){if(!e)return{};let t={};for(let n of e.split(/,(?![^=]*=)/)){let e=n.indexOf(`=`);if(e<0)continue;let r=n.slice(0,e).trim(),i=n.slice(e+1).trim(),a=t[r];a===void 0?t[r]=i:Array.isArray(a)?a.push(i):t[r]=[a,i]}return t}function formatCertDate(e){if(!e)return``;try{return e.format(`%b %d %H:%M:%S %Y GMT`)??``}catch{return``}}function formatAltNames(e){let t=[],n=e.get_dns_names();if(n)for(let e of n){let n=e.get_data();n&&t.push(`DNS:${new TextDecoder(`utf-8`).decode(n)}`)}let r=e.get_ip_addresses();if(r)for(let e of r)t.push(`IP Address:${e.to_string()}`);return t.join(`, `)}function fingerprintFromBytes(e,n){try{let r=new t.Checksum(n);r.update(e);let i=r.get_string();if(!i)return``;let a=[];for(let e=0;e<i.length;e+=2)a.push(i.slice(e,e+2).toUpperCase());return a.join(`:`)}catch{return``}}function tlsCertToPeerCert(n,r){let i={};try{i.subject=parseDistinguishedName(n.get_subject_name())}catch{}try{i.issuer=parseDistinguishedName(n.get_issuer_name())}catch{}i.subjectaltname=formatAltNames(n);try{i.valid_from=formatCertDate(n.get_not_valid_before()),i.valid_to=formatCertDate(n.get_not_valid_after())}catch{}try{let r=n,a=r.certificate_pem??r.certificatePem;if(a){let n=e(a);i.raw=n,i.fingerprint=fingerprintFromBytes(n,t.ChecksumType.SHA1),i.fingerprint256=fingerprintFromBytes(n,t.ChecksumType.SHA256)}}catch{}if(r)try{let e=n.get_issuer();e&&!e.is_same(n)?i.issuerCertificate=tlsCertToPeerCert(e,!0):e&&(i.issuerCertificate=i)}catch{}return i}export{fingerprintFromBytes,formatAltNames,formatCertDate,parseDistinguishedName,tlsCertToPeerCert};
|
package/lib/esm/internal/pem.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import e from"@girs/gio-2.0";function pemToString(e){
|
|
2
|
-
`)
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import e from"@girs/gio-2.0";function pemToString(e){return Array.isArray(e)?e.map(pemToString).join(`
|
|
2
|
+
`):typeof e==`string`?e:e instanceof Uint8Array?new TextDecoder(`utf-8`).decode(e):String(e)}function splitPemBlocks(e){let t=[],n=/-----BEGIN [^-]+-----[\s\S]*?-----END [^-]+-----/g,r;for(;(r=n.exec(e))!==null;)t.push(r[0]);return t}function buildGioCertificate(t,n){let r=pemToString(t),i=n?pemToString(n):``,a=i?`${r}\n${i}`:r;return e.TlsCertificate.new_from_pem(a,a.length)}function buildCaCertificates(t){let n=[];if(Array.isArray(t))for(let e of t)n.push(...splitPemBlocks(pemToString(e)));else n.push(...splitPemBlocks(pemToString(t)));let r=[];for(let t of n)try{r.push(e.TlsCertificate.new_from_pem(t,t.length))}catch{}return r}function pemToDer(e){let t=/-----BEGIN CERTIFICATE-----([\s\S]*?)-----END CERTIFICATE-----/.exec(e);if(!t)return new Uint8Array;let n=t[1].replace(/[\s\r\n]+/g,``);try{let e=globalThis.atob;if(!e)return new Uint8Array;let t=e(n),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);return r}catch{return new Uint8Array}}export{buildCaCertificates,buildGioCertificate,pemToDer,pemToString,splitPemBlocks};
|
package/lib/esm/tls-server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{checkHostMatch as e,splitHost as t}from"./internal/hostname.js";import{TLSSocket as n}from"./tls-socket.js";import{createSecureContext as r}from"./secure-context.js";import{parseClientHelloSni as i}from"./internal/sni-parser.js";import a from"@girs/gio-2.0";import o from"@girs/glib-2.0";import{Server as s}from"node:net";import{createNodeError as c,deferEmit as l}from"@gjsify/utils/core";var TLSServer=class extends s{_tlsCertificate=null;_tlsOptions;_sniContexts=new Map;_secureContext;constructor(e,t){super(),this._tlsOptions=e??{},this._secureContext=r(this._tlsOptions),this._tlsCertificate=this._secureContext.certificate,t&&this.on(`secureConnection`,t),this._tlsOptions.cert&&!this._tlsCertificate&&l(this,`error`,c(Error(`Failed to parse TLS certificate`),`createServer`,{}))}addContext(e,t){try{let n=r(t);this._sniContexts.set(e.toLowerCase(),n)}catch(e){this.emit(`error`,c(e,`addContext`,{}))}}_resolveSniContext(n,r){let i=this._secureContext;if(!n){r(i);return}let a=n.toLowerCase(),o=this._sniContexts.get(a);if(o){r(o);return}let s=t(a);for(let[t,n]of this._sniContexts)if(e(s,t)){r(n);return}if(this._tlsOptions.SNICallback)try{this._tlsOptions.SNICallback(n,(e,t)=>{if(e||!t){r(i);return}r(t)});return}catch{r(i);return}r(i)}listen(...e){return this.on(`connection`,e=>{this._upgradeTls(e)}),super.listen(...e)}_upgradeTls(e){let t=e._connection;if(!t){let t=Error(`Cannot upgrade socket: no underlying connection`);this.emit(`tlsClientError`,t,e),e.destroy();return}if(!this._tlsCertificate&&this._sniContexts.size===0&&!this._tlsOptions.SNICallback){let t=Error(`TLS server has no certificate configured`);this.emit(`tlsClientError`,t,e),e.destroy();return}let r=t,s=r.get_input_stream(),l=r.get_output_stream(),u=a.BufferedInputStream.new_sized(s,4096);u.fill_async(4096,o.PRIORITY_DEFAULT,null,(t,r)=>{let s=null;try{u.fill_finish(r),s=i(u.peek_buffer())}catch{}this._resolveSniContext(s,t=>{let r=t.certificate??this._tlsCertificate;if(!r){let t=Error(`SNI resolution returned no certificate`);this.emit(`tlsClientError`,t,e),e.destroy();return}try{let i=new a.SimpleIOStream({inputStream:u,outputStream:l}),s=a.TlsServerConnection.new(i,r);this._tlsOptions.requestCert?s.authenticationMode=this._tlsOptions.rejectUnauthorized===!1?a.TlsAuthenticationMode.REQUESTED:a.TlsAuthenticationMode.REQUIRED:s.authenticationMode=a.TlsAuthenticationMode.NONE;let d=!!this._tlsOptions.requestCert&&this._tlsOptions.rejectUnauthorized!==!1,f=this._secureContext.caCertificates;
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{checkHostMatch as e,splitHost as t}from"./internal/hostname.js";import{TLSSocket as n}from"./tls-socket.js";import{createSecureContext as r}from"./secure-context.js";import{parseClientHelloSni as i}from"./internal/sni-parser.js";import a from"@girs/gio-2.0";import o from"@girs/glib-2.0";import{Server as s}from"node:net";import{createNodeError as c,deferEmit as l}from"@gjsify/utils/core";var TLSServer=class extends s{_tlsCertificate=null;_tlsOptions;_sniContexts=new Map;_secureContext;constructor(e,t){super(),this._tlsOptions=e??{},this._secureContext=r(this._tlsOptions),this._tlsCertificate=this._secureContext.certificate,t&&this.on(`secureConnection`,t),this._tlsOptions.cert&&!this._tlsCertificate&&l(this,`error`,c(Error(`Failed to parse TLS certificate`),`createServer`,{}))}addContext(e,t){try{let n=r(t);this._sniContexts.set(e.toLowerCase(),n)}catch(e){this.emit(`error`,c(e,`addContext`,{}))}}_resolveSniContext(n,r){let i=this._secureContext;if(!n){r(i);return}let a=n.toLowerCase(),o=this._sniContexts.get(a);if(o){r(o);return}let s=t(a);for(let[t,n]of this._sniContexts)if(e(s,t)){r(n);return}if(this._tlsOptions.SNICallback)try{this._tlsOptions.SNICallback(n,(e,t)=>{if(e||!t){r(i);return}r(t)});return}catch{r(i);return}r(i)}listen(...e){return this.on(`connection`,e=>{this._upgradeTls(e)}),super.listen(...e)}_upgradeTls(e){let t=e._connection;if(!t){let t=Error(`Cannot upgrade socket: no underlying connection`);this.emit(`tlsClientError`,t,e),e.destroy();return}if(!this._tlsCertificate&&this._sniContexts.size===0&&!this._tlsOptions.SNICallback){let t=Error(`TLS server has no certificate configured`);this.emit(`tlsClientError`,t,e),e.destroy();return}let r=t,s=r.get_input_stream(),l=r.get_output_stream(),u=a.BufferedInputStream.new_sized(s,4096);u.fill_async(4096,o.PRIORITY_DEFAULT,null,(t,r)=>{let s=null;try{u.fill_finish(r),s=i(u.peek_buffer())}catch{}this._resolveSniContext(s,t=>{let r=t.certificate??this._tlsCertificate;if(!r){let t=Error(`SNI resolution returned no certificate`);this.emit(`tlsClientError`,t,e),e.destroy();return}try{let i=new a.SimpleIOStream({inputStream:u,outputStream:l}),s=a.TlsServerConnection.new(i,r);this._tlsOptions.requestCert?s.authenticationMode=this._tlsOptions.rejectUnauthorized===!1?a.TlsAuthenticationMode.REQUESTED:a.TlsAuthenticationMode.REQUIRED:s.authenticationMode=a.TlsAuthenticationMode.NONE;let d=!!this._tlsOptions.requestCert&&this._tlsOptions.rejectUnauthorized!==!1,f=this._secureContext.caCertificates;s.connect(`accept-certificate`,(e,t,n)=>{if(!d)return!0;if(f.length===0)return!1;for(let e of f)try{if(t.verify(null,e)===a.TlsCertificateFlags.NO_FLAGS)return!0}catch{}return!1}),this._tlsOptions.ALPNProtocols&&this._tlsOptions.ALPNProtocols.length>0&&s.set_advertised_protocols(this._tlsOptions.ALPNProtocols);let p=new a.Cancellable;s.handshake_async(o.PRIORITY_DEFAULT,p,(r,i)=>{try{s.handshake_finish(i);let e=new n;e.encrypted=!0,e.authorized=!0,e._secureContext=t,e._setupTlsStreams(s),e.alpnProtocol=e.getAlpnProtocol(),e._startReading(),this.emit(`secureConnection`,e)}catch(t){let n=c(t,`handshake`,{});this.emit(`tlsClientError`,n,e),e.destroy()}})}catch(t){let n=c(t,`tls_wrap`,{});this.emit(`tlsClientError`,n,e),e.destroy()}})})}};function createServer(e,t){return typeof e==`function`?new TLSServer(void 0,e):new TLSServer(e,t)}export{TLSServer,createServer};
|
package/lib/esm/tls-socket.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./_virtual/_rolldown/runtime.js";import{tlsCertToPeerCert as e}from"./internal/cert-utils.js";import{createSessionAccess as t,hasTlsSessionAccess as n}from"./session-access.js";import r from"@girs/gio-2.0";import{Buffer as i}from"node:buffer";import{Socket as a}from"node:net";var TLSSocket=class extends a{encrypted=!0;authorized=!1;authorizationError;alpnProtocol=!1;servername;_tlsConnection=null;_secureContext=null;_sessionAccess=null;constructor(e,t){super()}_setupTlsStreams(e){this._tlsConnection=e;let t=this;t._inputStream=e.get_input_stream(),t._outputStream=e.get_output_stream(),t._connection=e}_getSessionAccess(){if(this._sessionAccess)return this._sessionAccess;if(!this._tlsConnection)return null;try{this._sessionAccess=t(this._tlsConnection)}catch{this._sessionAccess=null}return this._sessionAccess}getPeerCertificate(t=!1){if(!this._tlsConnection)return{};try{let n=this._tlsConnection.get_peer_certificate();return n?e(n,t):{}}catch{return{}}}getProtocol(){if(!this._tlsConnection)return null;
|
|
1
|
+
import"./_virtual/_rolldown/runtime.js";import{tlsCertToPeerCert as e}from"./internal/cert-utils.js";import{createSessionAccess as t,hasTlsSessionAccess as n}from"./session-access.js";import r from"@girs/gio-2.0";import{Buffer as i}from"node:buffer";import{Socket as a}from"node:net";var TLSSocket=class extends a{encrypted=!0;authorized=!1;authorizationError;alpnProtocol=!1;servername;_tlsConnection=null;_secureContext=null;_sessionAccess=null;constructor(e,t){super()}_setupTlsStreams(e){this._tlsConnection=e;let t=this;t._inputStream=e.get_input_stream(),t._outputStream=e.get_output_stream(),t._connection=e}_getSessionAccess(){if(this._sessionAccess)return this._sessionAccess;if(!this._tlsConnection)return null;try{this._sessionAccess=t(this._tlsConnection)}catch{this._sessionAccess=null}return this._sessionAccess}getPeerCertificate(t=!1){if(!this._tlsConnection)return{};try{let n=this._tlsConnection.get_peer_certificate();return n?e(n,t):{}}catch{return{}}}getProtocol(){if(!this._tlsConnection)return null;switch(this._tlsConnection.get_protocol_version()){case r.TlsProtocolVersion.TLS_1_0:return`TLSv1`;case r.TlsProtocolVersion.TLS_1_1:return`TLSv1.1`;case r.TlsProtocolVersion.TLS_1_2:return`TLSv1.2`;case r.TlsProtocolVersion.TLS_1_3:return`TLSv1.3`;default:return null}}getCipher(){return this._tlsConnection?{name:this._tlsConnection.get_ciphersuite_name()||`unknown`,version:this.getProtocol()||`unknown`}:null}getAlpnProtocol(){return this._tlsConnection&&this._tlsConnection.get_negotiated_protocol()||!1}getFinished(){if(!n())return;let e=this._getSessionAccess();if(e)try{return _bytesToBuffer(e.get_finished())}catch{return}}getPeerFinished(){if(!n())return;let e=this._getSessionAccess();if(e)try{return _bytesToBuffer(e.get_peer_finished())}catch{return}}getSession(){if(!n())return;let e=this._getSessionAccess();if(e)try{return _bytesToBuffer(e.get_session_data())}catch{return}}setSession(e){if(!n())return;let t=this._getSessionAccess();if(t)try{t.set_session_data(_bufferToBytes(e))}catch{}}isSessionReused(){if(!n())return!1;let e=this._getSessionAccess();if(!e)return!1;try{return e.is_session_reused()}catch{return!1}}};function _bytesToBuffer(e){if(e==null)return;if(e instanceof Uint8Array)return i.from(e);let t=e;if(typeof t.toArray==`function`)try{return i.from(t.toArray())}catch{return}}function _bufferToBytes(e){return e}export{TLSSocket};
|
|
@@ -75,7 +75,14 @@ export declare class TLSSocket extends Socket {
|
|
|
75
75
|
* recursively (with a self-reference on the root for compatibility).
|
|
76
76
|
*/
|
|
77
77
|
getPeerCertificate(detailed?: boolean): PeerCertificate;
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Get the negotiated TLS protocol version.
|
|
80
|
+
*
|
|
81
|
+
* No try/catch here or in the two getters below: get_protocol_version,
|
|
82
|
+
* get_ciphersuite_name and get_negotiated_protocol are plain GObject
|
|
83
|
+
* property getters with no throw path in the GIR, and all exist since
|
|
84
|
+
* GLib 2.70 (below our runtime floor).
|
|
85
|
+
*/
|
|
79
86
|
getProtocol(): string | null;
|
|
80
87
|
/** Get the negotiated cipher suite name + version. */
|
|
81
88
|
getCipher(): {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/tls",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Node.js tls module for Gjs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
"tls"
|
|
38
38
|
],
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@gjsify/cli": "^0.
|
|
41
|
-
"@gjsify/unit": "^0.
|
|
40
|
+
"@gjsify/cli": "^0.26.0",
|
|
41
|
+
"@gjsify/unit": "^0.26.0",
|
|
42
42
|
"@types/node": "^25.9.2",
|
|
43
43
|
"typescript": "^6.0.3"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@girs/gio-2.0": "^4.1.0",
|
|
47
47
|
"@girs/glib-2.0": "^4.1.0",
|
|
48
|
-
"@gjsify/net": "^0.
|
|
49
|
-
"@gjsify/tls-native": "^0.
|
|
50
|
-
"@gjsify/utils": "^0.
|
|
48
|
+
"@gjsify/net": "^0.26.0",
|
|
49
|
+
"@gjsify/tls-native": "^0.26.0",
|
|
50
|
+
"@gjsify/utils": "^0.26.0"
|
|
51
51
|
},
|
|
52
52
|
"gjsify": {
|
|
53
53
|
"runtimes": {
|