mirror of
https://git.proxmox.com/git/package-rebuilds
synced 2025-08-21 21:19:51 +00:00
127 lines
3.2 KiB
JavaScript
127 lines
3.2 KiB
JavaScript
'use strict'
|
|
|
|
const crypto = require('crypto')
|
|
const https = require('https')
|
|
const { test } = require('tap')
|
|
const { Client, buildConnector } = require('..')
|
|
const pem = require('https-pem')
|
|
|
|
const caFingerprint = getFingerprint(pem.cert.toString()
|
|
.split('\n')
|
|
.slice(1, -1)
|
|
.map(line => line.trim())
|
|
.join('')
|
|
)
|
|
|
|
test('Validate CA fingerprint with a custom connector', t => {
|
|
t.plan(2)
|
|
|
|
const server = https.createServer(pem, (req, res) => {
|
|
res.setHeader('Content-Type', 'text/plain')
|
|
res.end('hello')
|
|
})
|
|
|
|
server.listen(0, function () {
|
|
const connector = buildConnector({ rejectUnauthorized: false })
|
|
const client = new Client(`https://localhost:${server.address().port}`, {
|
|
connect (opts, cb) {
|
|
connector(opts, (err, socket) => {
|
|
if (err) {
|
|
cb(err)
|
|
} else if (getIssuerCertificate(socket).fingerprint256 !== caFingerprint) {
|
|
socket.destroy()
|
|
cb(new Error('Fingerprint does not match'))
|
|
} else {
|
|
cb(null, socket)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.teardown(() => {
|
|
client.close()
|
|
server.close()
|
|
})
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, data) => {
|
|
t.error(err)
|
|
|
|
data.body
|
|
.resume()
|
|
.on('end', () => {
|
|
t.pass()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('Bad CA fingerprint with a custom connector', t => {
|
|
t.plan(2)
|
|
|
|
const server = https.createServer(pem, (req, res) => {
|
|
res.setHeader('Content-Type', 'text/plain')
|
|
res.end('hello')
|
|
})
|
|
|
|
server.listen(0, function () {
|
|
const connector = buildConnector({ rejectUnauthorized: false })
|
|
const client = new Client(`https://localhost:${server.address().port}`, {
|
|
connect (opts, cb) {
|
|
connector(opts, (err, socket) => {
|
|
if (err) {
|
|
cb(err)
|
|
} else if (getIssuerCertificate(socket).fingerprint256 !== 'FO:OB:AR') {
|
|
socket.destroy()
|
|
cb(new Error('Fingerprint does not match'))
|
|
} else {
|
|
cb(null, socket)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
t.teardown(() => {
|
|
client.close()
|
|
server.close()
|
|
})
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, data) => {
|
|
t.equal(err.message, 'Fingerprint does not match')
|
|
t.equal(data.body, undefined)
|
|
})
|
|
})
|
|
})
|
|
|
|
function getIssuerCertificate (socket) {
|
|
let certificate = socket.getPeerCertificate(true)
|
|
while (certificate && Object.keys(certificate).length > 0) {
|
|
// 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
|
|
}
|
|
|
|
function getFingerprint (content, inputEncoding = 'base64', outputEncoding = 'hex') {
|
|
const shasum = crypto.createHash('sha256')
|
|
shasum.update(content, inputEncoding)
|
|
const res = shasum.digest(outputEncoding)
|
|
return res.toUpperCase().match(/.{1,2}/g).join(':')
|
|
}
|