From ed752f4f5819a6e13e8af4280d674b75ed66c1af Mon Sep 17 00:00:00 2001 From: Tomas Della Vedova Date: Fri, 30 Jul 2021 16:54:04 +0200 Subject: [PATCH] Improve getIssuerCertificate utility (#909) --- docs/api/Connector.md | 20 ++++++++++++-------- examples/ca-fingerprint/index.js | 20 ++++++++++++-------- test/ca-fingerprint.js | 18 +++++++++++------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/docs/api/Connector.md b/docs/api/Connector.md index 597c91f6079..fe446b46e62 100644 --- a/docs/api/Connector.md +++ b/docs/api/Connector.md @@ -67,7 +67,7 @@ const client = new Client('https://localhost:3000', { cb(err) } else if (getIssuerCertificate(socket).fingerprint256 !== caFingerprint) { socket.destroy() - cb(new Error('Fingerprint does not match')) + cb(new Error('Fingerprint does not match or malformed certificate')) } else { cb(null, socket) } @@ -94,15 +94,19 @@ client.request({ function getIssuerCertificate (socket) { let certificate = socket.getPeerCertificate(true) while (certificate && Object.keys(certificate).length > 0) { - if (certificate.issuerCertificate !== undefined) { - // For self-signed certificates, `issuerCertificate` may be a circular reference. - if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { - break - } - certificate = certificate.issuerCertificate - } else { + // invalid certificate + if (certificate.issuerCertificate == null) { + return null + } + + // We have reached the root certificate. + // In case of self-signed certificates, `issuerCertificate` may be a circular reference. + if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { break } + + // continue the loop + certificate = certificate.issuerCertificate } return certificate } diff --git a/examples/ca-fingerprint/index.js b/examples/ca-fingerprint/index.js index 4ac9b9f80cc..792c08c64b1 100644 --- a/examples/ca-fingerprint/index.js +++ b/examples/ca-fingerprint/index.js @@ -26,7 +26,7 @@ server.listen(0, function () { cb(err) } else if (getIssuerCertificate(socket).fingerprint256 !== caFingerprint) { socket.destroy() - cb(new Error('Fingerprint does not match')) + cb(new Error('Fingerprint does not match or malformed certificate')) } else { cb(null, socket) } @@ -55,15 +55,19 @@ server.listen(0, function () { function getIssuerCertificate (socket) { let certificate = socket.getPeerCertificate(true) while (certificate && Object.keys(certificate).length > 0) { - if (certificate.issuerCertificate !== undefined) { - // For self-signed certificates, `issuerCertificate` may be a circular reference. - if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { - break - } - certificate = certificate.issuerCertificate - } else { + // invalid certificate + if (certificate.issuerCertificate == null) { + return null + } + + // We have reached the root certificate. + // In case of self-signed certificates, `issuerCertificate` may be a circular reference. + if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { break } + + // continue the loop + certificate = certificate.issuerCertificate } return certificate } diff --git a/test/ca-fingerprint.js b/test/ca-fingerprint.js index 2d537c90730..f71063fb934 100644 --- a/test/ca-fingerprint.js +++ b/test/ca-fingerprint.js @@ -101,15 +101,19 @@ test('Bad CA fingerprint with a custom connector', t => { function getIssuerCertificate (socket) { let certificate = socket.getPeerCertificate(true) while (certificate && Object.keys(certificate).length > 0) { - if (certificate.issuerCertificate !== undefined) { - // For self-signed certificates, `issuerCertificate` may be a circular reference. - if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { - break - } - certificate = certificate.issuerCertificate - } else { + // invalid certificate + if (certificate.issuerCertificate == null) { + return null + } + + // We have reached the root certificate. + // In case of self-signed certificates, `issuerCertificate` may be a circular reference. + if (certificate.fingerprint256 === certificate.issuerCertificate.fingerprint256) { break } + + // continue the loop + certificate = certificate.issuerCertificate } return certificate }