* @param {{subject: {CN: string}, subjectaltname: string?}} cert A certificate object as defined by * TLS module https://nodejs.org/docs/latest-v12.x/api/tls.html#tls_certificate_object * @param {string} sniAddress * @returns {Error|undefined} Similar to tls.checkServerIdentity() returns an Error
(cert, sniAddress)
| 227 | * @ignore |
| 228 | */ |
| 229 | function checkServerIdentity(cert, sniAddress) { |
| 230 | // Based on logic defined by the Node.js Core module |
| 231 | // https://github.com/nodejs/node/blob/ff48009fefcecedfee2c6ff1719e5be3f6969049/lib/tls.js#L212-L290 |
| 232 | |
| 233 | // SNI address is composed by hostname and port |
| 234 | const hostName = sniAddress.split(':')[0]; |
| 235 | const altNames = cert.subjectaltname; |
| 236 | const cn = cert.subject.CN; |
| 237 | |
| 238 | if (hostName === cn) { |
| 239 | // quick check based on common name |
| 240 | return undefined; |
| 241 | } |
| 242 | |
| 243 | const parsedAltNames = []; |
| 244 | if (altNames) { |
| 245 | for (const name of altNames.split(', ')) { |
| 246 | if (name.startsWith('DNS:')) { |
| 247 | parsedAltNames.push(name.slice(4)); |
| 248 | } else if (name.startsWith('URI:')) { |
| 249 | parsedAltNames.push(new URL(name.slice(4)).hostname); |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | const hostParts = hostName.split('.'); |
| 255 | const wildcard = (pattern) => checkParts(hostParts, pattern); |
| 256 | |
| 257 | let valid; |
| 258 | if (parsedAltNames.length > 0) { |
| 259 | valid = parsedAltNames.some(wildcard); |
| 260 | } else { |
| 261 | // Use the common name |
| 262 | valid = wildcard(cn); |
| 263 | } |
| 264 | |
| 265 | if (!valid) { |
| 266 | const error = new Error(`Host: ${hostName} is not cert's CN/altnames: ${cn} / ${altNames}`); |
| 267 | error.reason = error.message; |
| 268 | error.host = hostName; |
| 269 | error.cert = cert; |
| 270 | return error; |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | /** |
| 275 | * Simplified version of Node.js tls core lib check() function |