I'm trying to set up a https server with mutual authentication.
I created the key and the certificate for the server (auto-signed).
Now I use firefox to connect to the server without providing any client certificate.
This should result in the req.socket.authorized
being false
(as stated here), but for some reason after some refreshes (and without changing anything) the message change from the right
Unauthorized: Client certificate required (UNABLE_TO_GET_ISSUER_CERT)
to
Client certificate was authenticated but certificate information could not be retrieved.
To me this is unexpected, because it means that req.socket.authorized == true
even without client certificates. Can someone explain me why is this happening?
Here my code:
const express = require('express')
const app = express()
const fs = require('fs')
const https = require('https')
// ...
const opts = { key: fs.readFileSync('./cryptoMaterial/private_key.pem'),
cert: fs.readFileSync('./cryptoMaterial/certificate.pem'),
requestCert: true,
rejectUnauthorized: false,
ca: [ fs.readFileSync('./cryptoMaterial/certificate.pem') ]
}
const clientAuthMiddleware = () => (req, res, next) => {
if (!req.secure && req.header('x-forwarded-proto') != 'https') {
return res.redirect('https://' + req.header('host') + req.url);
}
// Ensure that the certificate was validated at the protocol level
if (!req.socket.authorized) { // <-- THIS SHOULD BE ALWAYS FALSE
res.status(401).send(
'Unauthorized: Client certificate required ' +
'(' + req.socket.authorizationError + ')'
);
return
}
// Obtain certificate details
var cert = req.socket.getPeerCertificate();
if (!cert || !Object.keys(cert).length) {
// Handle the bizarre and probably not-real case that a certificate was
// validated but we can't actually inspect it
res.status(500).send(
'Client certificate was authenticated but certificate ' +
'information could not be retrieved.'
);
return
}
return next();
};
app.use(clientAuthMiddleware());
// ...
https.createServer(opts, app).listen(PORT)