| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent c8668be commit d1be630
1 file changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -114,6 +114,82 @@ const kIsVerified = Symbol('verified'); | |||
| 114 | 114 | ||
| 115 | 115 | const noop = () => {}; | |
| 116 | 116 | ||
| 117 | + const kTLSSessionStatePrefix = Buffer.from('\0nodejs:tls:session:1\0'); | ||
| 118 | + | ||
| 119 | + function getSessionServerIdentity(options) { | ||
| 120 | + return options?.servername || | ||
| 121 | + options?.host || | ||
| 122 | + options?.socket?._host || | ||
| 123 | + 'localhost'; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + function wrapSessionState(session, options) { | ||
| 127 | + if (!Buffer.isBuffer(session) || options?.isServer) | ||
| 128 | + return session; | ||
| 129 | + | ||
| 130 | + const servername = Buffer.from(getSessionServerIdentity(options), 'utf8'); | ||
| 131 | + const servernameLength = Buffer.allocUnsafe(2); | ||
| 132 | + servernameLength.writeUInt16BE(servername.length, 0); | ||
| 133 | + | ||
| 134 | + return Buffer.concat([ | ||
| 135 | + kTLSSessionStatePrefix, | ||
| 136 | + servernameLength, | ||
| 137 | + servername, | ||
| 138 | + session, | ||
| 139 | + ]); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + function unwrapSessionState(session) { | ||
| 143 | + if (!Buffer.isBuffer(session) || | ||
| 144 | + session.length < kTLSSessionStatePrefix.length + 2 || | ||
| 145 | + Buffer.compare( | ||
| 146 | + session.subarray(0, kTLSSessionStatePrefix.length), | ||
| 147 | + kTLSSessionStatePrefix, | ||
| 148 | + ) !== 0) { | ||
| 149 | + return; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + const start = kTLSSessionStatePrefix.length; | ||
| 153 | + const servernameLength = session.readUInt16BE(start); | ||
| 154 | + const servernameStart = start + 2; | ||
| 155 | + const servernameEnd = servernameStart + servernameLength; | ||
| 156 | + if (session.length < servernameEnd) | ||
| 157 | + return; | ||
| 158 | + | ||
| 159 | + return { | ||
| 160 | + servername: session.toString('utf8', servernameStart, servernameEnd), | ||
| 161 | + session: session.subarray(servernameEnd), | ||
| 162 | + }; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + function getSessionForReuse(session, options) { | ||
| 166 | + if (typeof session === 'string') | ||
| 167 | + session = Buffer.from(session, 'latin1'); | ||
| 168 | + | ||
| 169 | + if (options?.isServer) | ||
| 170 | + return session; | ||
| 171 | + | ||
| 172 | + const wrappedSession = unwrapSessionState(session); | ||
| 173 | + if (wrappedSession !== undefined) { | ||
| 174 | + const servername = getSessionServerIdentity(options); | ||
| 175 | + if (wrappedSession.servername !== servername) { | ||
| 176 | + debug('ignore session for %s: authenticated for %s', | ||
| 177 | + servername, wrappedSession.servername); | ||
| 178 | + return; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + return wrappedSession.session; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + if (Buffer.isBuffer(session) && options?.rejectUnauthorized !== false) { | ||
| 185 | + debug('ignore raw session for verified client connection to %s', | ||
| 186 | + getSessionServerIdentity(options)); | ||
| 187 | + return; | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + return session; | ||
| 191 | + } | ||
| 192 | + | ||
| 117 | 193 | let tlsTracingWarned = false; | |
| 118 | 194 | ||
| 119 | 195 | // Server side times how long a handshake is taking to protect against slow | |
@@ -341,10 +417,11 @@ function requestOCSPDone(socket) { | |||
| 341 | 417 | function onnewsessionclient(sessionId, session) { | |
| 342 | 418 | debug('client emit session'); | |
| 343 | 419 | const owner = this[owner_symbol]; | |
| 420 | + const wrappedSession = wrapSessionState(session, owner[kConnectOptions]); | ||
| 344 | 421 | if (owner[kIsVerified]) { | |
| 345 | - owner.emit('session', session); | ||
| 422 | + owner.emit('session', wrappedSession); | ||
| 346 | 423 | } else { | |
| 347 | - owner[kPendingSession] = session; | ||
| 424 | + owner[kPendingSession] = wrappedSession; | ||
| 348 | 425 | } | |
| 349 | 426 | } | |
| 350 | 427 | ||
@@ -1139,9 +1216,19 @@ TLSSocket.prototype.setServername = function(name) { | |||
| 1139 | 1216 | }; | |
| 1140 | 1217 | ||
| 1141 | 1218 | TLSSocket.prototype.setSession = function(session) { | |
| 1142 | - if (typeof session === 'string') | ||
| 1143 | - session = Buffer.from(session, 'latin1'); | ||
| 1144 | - this._handle.setSession(session); | ||
| 1219 | + session = getSessionForReuse(session, this[kConnectOptions] || this._tlsOptions); | ||
| 1220 | + if (session !== undefined) | ||
| 1221 | + this._handle.setSession(session); | ||
| 1222 | + }; | ||
| 1223 | + | ||
| 1224 | + TLSSocket.prototype.getSession = function() { | ||
| 1225 | + if (!this._handle) | ||
| 1226 | + return null; | ||
| 1227 | + | ||
| 1228 | + return wrapSessionState( | ||
| 1229 | + this._handle.getSession(), | ||
| 1230 | + this[kConnectOptions] || this._tlsOptions, | ||
| 1231 | + ); | ||
| 1145 | 1232 | }; | |
| 1146 | 1233 | ||
| 1147 | 1234 | TLSSocket.prototype.getPeerCertificate = function(detailed) { | |
@@ -1200,7 +1287,6 @@ function makeSocketMethodProxy(name) { | |||
| 1200 | 1287 | 'getFinished', | |
| 1201 | 1288 | 'getPeerFinished', | |
| 1202 | 1289 | 'getProtocol', | |
| 1203 | - 'getSession', | ||
| 1204 | 1290 | 'getTLSTicket', | |
| 1205 | 1291 | 'isSessionReused', | |
| 1206 | 1292 | 'enableTrace', | |
@@ -1663,12 +1749,11 @@ function onConnectSecure() { | |||
| 1663 | 1749 | // Verify that server's identity matches it's certificate's names | |
| 1664 | 1750 | // Unless server has resumed our existing session | |
| 1665 | 1751 | if (!verifyError && !this.isSessionReused()) { | |
| 1666 | - const hostname = options.servername || | ||
| 1667 | - options.host || | ||
| 1668 | - (options.socket?._host) || | ||
| 1669 | - 'localhost'; | ||
| 1670 | 1752 | const cert = this.getPeerCertificate(true); | |
| 1671 | - verifyError = options.checkServerIdentity(hostname, cert); | ||
| 1753 | + verifyError = options.checkServerIdentity( | ||
| 1754 | + getSessionServerIdentity(options), | ||
| 1755 | + cert, | ||
| 1756 | + ); | ||
| 1672 | 1757 | } | |
| 1673 | 1758 | ||
| 1674 | 1759 | if (verifyError) { | |
@@ -1753,6 +1838,8 @@ exports.connect = function connect(...args) { | |||
| 1753 | 1838 | ); | |
| 1754 | 1839 | } | |
| 1755 | 1840 | ||
| 1841 | + options.session = getSessionForReuse(options.session, options); | ||
| 1842 | + | ||
| 1756 | 1843 | const tlssock = new TLSSocket(options.socket, { | |
| 1757 | 1844 | allowHalfOpen: options.allowHalfOpen, | |
| 1758 | 1845 | pipe: !!options.path, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments