Validate certificates NodeJS - node.js

Is there any way to validate certificates against a CA, similar to the command "openssl verify -CAfile"?
I need to do this to bypass the HTTPS check Node JS with rejectUnauthorized: true, because with selfsigned certificates already realized that it is virtually impossible to authenticate the client with SSL.

Related

TLS handshake fail. HTTPS request to HAproxy to http and then encrypt it again to forward request to ssl server

Need help!!! . I have an https request and need to intercept it, read values and forward the same ssl request to the destination. I have all the required crt, key, CA with me. I am aware that Haproxy ACL does not work with L4 layer but I'm trying to find a workaround to decrypt the message, read the message, encrypt it again and forward. The reason for reading message is to using ACL i need to read the path difference in carious request and route the request to different servers accordingly. I am trying to intercept the client request to server, the request by default is SSL and server is expecting an SSL request
ssl crt: created a new user with new crt-key pair and used Certificate Signing Requests of server to authenticate it against CA in server
The scenario is that I have an incoming SSL request which I'm capturing into frontend of haproxy with the server certificate, while forwarding that request to a test webserver I am able to see that it has changed from HTTPS to HTTP. Now when I try re-encrypt it, the original destination is not able to accept the request since it is not SSL, I have tried to add the certs in the backend but not useful. Please check my current Haproxy config and please help if possible. I am not an expert in Network communication/ Encryption/ HaProxy.
frontend test
bind IP:6443 ssl crt <location>
option httplog
mode http
default_backend testback
backend testback
mode http
balance roundrobin
option http-check
server <host> IP:6443 check fall 3 rise 2 ssl verify required ca-file <loc> crt <loc>
To verify my certicates are valid and connecting:
openssl s_client -connect :6443 -cert myuser.crt -key myuser.key -CAfile ca.crt
Output:
SSL handshake has read 1619 bytes and written 2239 bytes
Verification: OK
So no problem with Certicates i presume, problem while using Ha proxy for connection
Error:
Unable to connect to the server: x509: certificate specifies an incompatible key usage
Ha proxy error:
2021-08-12T14:45:36.930478+02:00 parasilo-27 haproxy[21562]: :34672 [12/Aug/2021:14:45:36.927] server/1: SSL handshake failure
2021-08-12T14:45:37+02:00 localhost haproxy[21562]: :34674 [12/Aug/2021:14:45:37.438] server/1: SSL handshake failure
To sum up what was analyzed in the comments, as asked. Perhaps it will be useful to somebody someday.
Haproxy's config turned out to be correct, but generated certificates had wrong extended key usage (X509v3 extension).
Command to list extended key usage:
openssl x509 -in /path/to/cert.pem -noout -ext extendedKeyUsage
Often, when bought on internet, it shows X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication. Original Poster used self-signed, self-generated certificates and his certificate used on haproxy's frontend had only TLS Web Client Authentication, where frontend requires TLS Web Server Authentication if this extensions is used at all.
That resulted in the error message:
Error: kubectl get po: Unable to connect to the server: x509: certificate specifies an incompatible key usage
As a consequence haproxy logged SSL handshake failure without any more details, as is its habit.
After adding TLS Web Server Authentication to certificate in haproxy's frontend section and TLS Web Client Authentication to certificate in haproxy's backend section Original Poster reported success.

How to authenticate user with CAC in Node/Express

I need to allow users to log into my react website using their DoD issued Common Access Card. I am using an express api as an authentication server. I've got the server configured to require a client cert:
const options = {
key: fs.readFileSync(config.ssl.keyPath),
cert: fs.readFileSync(config.ssl.certPath),
ca: [fs.readFileSync(config.ssl.caPath)],
requestCert: true,
rejectUnauthorized: false,
};
https.createServer(options, expressApp).listen(port);
How do I get my react app to request/load/read the certificate from the CAC?
You will need to create a .PFX cert and import it into the browser's certificate store. The certificate generated should be signed by the CA used to start your express server. The certificate imported into your browser should also be enabled for "Client Authentication".

node.js: HTTPS client certificate without server validation?

I have a https server and client in node.js.
For 'normal' HTTPS a host lets in any client, and the client authenticates the host.
However in my situation I would like to do the opposite:
I want the host to authenticate the client, but the client to connect to any host without authenticating it. ie: The host does not get a key/crt (but does trust the CA), while the client does gets a key/crt (and also trusts the CA).
The standard way for https with both sides authenticating each other is:
Server options:
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-crt.pem'),
ca: fs.readFileSync('ca-crt.pem'),
requestCert: true,
rejectUnauthorized: true
Client options:
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-crt.pem'),
ca: fs.readFileSync('ca-crt.pem') };
I removed key and crt from server, but how to tell the client not to request server/host cert? I can't seem to figure that part out? The documentation claims that for a client rejectUnauthorized must be set to true for the client to validate the server, so I set it to false. But the TLS handshake seems to be failing.

Socket.IO TLS requiring key/cert

I have a CA from an authorized server. I have set up my HTTPS and WebSocket setup as follows:
var httpsOptions = {
cert: fs.readFileSync(config.ssl.server_cert),
key: fs.readFileSync(config.ssl.server_key),
requestCert: true,
rejectUnauthorized: true,
passphrase: config.ssl.server_password
};
httpsServer.listen(config.https_port, function () {
console.info("HTTPS server running on %d", config.https_port);
});
io = io.listen(server);
io.sockets.on('connection', function (socket) {
console.log("connected: " + socket.id);
})
Now, my clients will have to sign up for an account. When they do, I want to create a private/public key for them, and sign it with the CA that I have. They then have to use them for any web socket connection. If these are not provided, I don't want to even allow a connection.
My client at the moment is then:
io.connect(url, {secure: true, 'force new connection': true});
But I cannot figure out how to A) pass the key to the server, and B) If this is even possible?
If you're talking about browsers, then the client certificate and private key has to be installed in the browser or OS certificate store (depending on which browser is being used). Once installed, the browser will automatically send the certificate.
Unfortunately, client certificate installation is not a user-friendly process.
If your client is a node process, a client cert option was (finally) added in socket.io 1.3.
Don't forget to validate that the presented certificate matches a user account in your system. rejectUnauthorized only validates that the client presented a certificate issued by any trusted CA.
Do you mean you have a SSL certificate for your server? You can't sign new certificates with that. No trusted root CA gives out certs that allow third parties to sign certs without a very long process and lots of money.
You can run your own CA that signs client certificates. You have to configure your server to trust your client certificate-issuing CA (via the ca option in createServer) since it will be untrusted by default.

Node.js Prevent to connect with revoked certificate

How to configure https server to prevent connect with revoked certificate
Solved: add to https options crl property - certificate revokation list
crl: fs.readFileSync(path.join('public', "ca-crl.pem"))

Resources